/src/scnlib/include/scn/external/nanorange/nanorange.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // NanoRange WITH MODIFICATION at line 3338 |
2 | | |
3 | | // nanorange.hpp |
4 | | // |
5 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8 | | |
9 | | #ifndef NANORANGE_HPP_INCLUDED |
10 | | #define NANORANGE_HPP_INCLUDED |
11 | | |
12 | | // nanorange/algorithm.hpp |
13 | | // |
14 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17 | | |
18 | | #ifndef NANORANGE_ALGORITHM_HPP_INCLUDED |
19 | | #define NANORANGE_ALGORITHM_HPP_INCLUDED |
20 | | |
21 | | // Algorithms reimplemented in Nanorange |
22 | | // nanorange/algorithm/adjacent_find.hpp |
23 | | // |
24 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
25 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
26 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
27 | | |
28 | | #ifndef NANORANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED |
29 | | #define NANORANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED |
30 | | |
31 | | // nanorange/range.hpp |
32 | | // |
33 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
34 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
35 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
36 | | |
37 | | #ifndef NANORANGE_RANGES_HPP_INCLUDED |
38 | | #define NANORANGE_RANGES_HPP_INCLUDED |
39 | | |
40 | | // nanorange/detail/iterator/algorithm_requirements.hpp |
41 | | // |
42 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
43 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
44 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
45 | | |
46 | | #ifndef NANORANGE_DETAIL_ITERATOR_ALGORITHM_REQUIREMENTS_HPP_INCLUDED |
47 | | #define NANORANGE_DETAIL_ITERATOR_ALGORITHM_REQUIREMENTS_HPP_INCLUDED |
48 | | |
49 | | // nanorange/detail/functional/comparisons.hpp |
50 | | // |
51 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
52 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
53 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
54 | | |
55 | | #ifndef NANORANGE_DETAIL_FUNCTIONAL_COMPARISONS_HPP_INCLUDED |
56 | | #define NANORANGE_DETAIL_FUNCTIONAL_COMPARISONS_HPP_INCLUDED |
57 | | |
58 | | // nanorange/detail/concepts/comparison.hpp |
59 | | // |
60 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
61 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
62 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
63 | | |
64 | | #ifndef NANORANGE_DETAIL_CONCEPTS_COMPARISON_HPP_INCLUDED |
65 | | #define NANORANGE_DETAIL_CONCEPTS_COMPARISON_HPP_INCLUDED |
66 | | |
67 | | // nanorange/detail/concepts/core.hpp |
68 | | // |
69 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
70 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
71 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
72 | | |
73 | | #ifndef NANORANGE_DETAIL_CONCEPTS_CORE_HPP_INCLUDED |
74 | | #define NANORANGE_DETAIL_CONCEPTS_CORE_HPP_INCLUDED |
75 | | |
76 | | // nanorange/detail/macros.hpp |
77 | | // |
78 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
79 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
80 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
81 | | |
82 | | #ifndef NANORANGE_DETAIL_MACROS_HPP_INCLUDED |
83 | | #define NANORANGE_DETAIL_MACROS_HPP_INCLUDED |
84 | | |
85 | | #include <ciso646> |
86 | | |
87 | | #ifdef NANORANGE_NO_DEPRECATION_WARNINGS |
88 | | #define NANO_DEPRECATED |
89 | | #define NANO_DEPRECATED_FOR(x) |
90 | | #else |
91 | | #define NANO_DEPRECATED [[deprecated]] |
92 | | #define NANO_DEPRECATED_FOR(x) [[deprecated(x)]] |
93 | | #endif |
94 | | |
95 | | #ifdef __has_cpp_attribute |
96 | | #if __has_cpp_attribute(no_unique_address) >= 201803L |
97 | | #define NANO_NO_UNIQUE_ADDRESS [[no_unique_address]] |
98 | | #else |
99 | | #define NANO_NO_UNIQUE_ADDRESS |
100 | | #endif // __has_cpp_attribute(no_unique_address) |
101 | | #else |
102 | | #define NANO_NO_UNIQUE_ADDRESS |
103 | | #endif // defined(__has_cpp_attribute) |
104 | | |
105 | | #define NANO_CONCEPT inline constexpr bool |
106 | | |
107 | | #define NANO_BEGIN_NAMESPACE \ |
108 | | \ |
109 | | namespace nano { \ |
110 | | \ |
111 | | inline namespace ranges { |
112 | | |
113 | | #define NANO_END_NAMESPACE \ |
114 | | } \ |
115 | | } |
116 | | |
117 | | #define NANO_INLINE_VAR(type, name) \ |
118 | | inline namespace function_objects { \ |
119 | | inline constexpr type name{}; \ |
120 | | } |
121 | | |
122 | | #if defined(_LIBCPP_VERSION) |
123 | | #define NANO_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD |
124 | | #define NANO_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
125 | | #elif defined(_MSVC_STL_VERSION) |
126 | | #define NANO_BEGIN_NAMESPACE_STD _STD_BEGIN |
127 | | #define NANO_END_NAMESPACE_STD _STD_END |
128 | | #elif defined(_GLIBCXX_DEBUG) |
129 | | #ifndef NANORANGE_NO_STD_FORWARD_DECLARATIONS |
130 | | #define NANORANGE_NO_STD_FORWARD_DECLARATIONS |
131 | | #endif |
132 | | #else |
133 | | #define NANO_BEGIN_NAMESPACE_STD namespace std { |
134 | | #define NANO_END_NAMESPACE_STD } |
135 | | #endif |
136 | | |
137 | | #if defined(_MSC_VER) |
138 | | #define NANO_MSVC_LAMBDA_PIPE_WORKAROUND 1 |
139 | | #endif |
140 | | |
141 | | #endif |
142 | | |
143 | | // nanorange/type_traits.hpp |
144 | | // |
145 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
146 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
147 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
148 | | |
149 | | #ifndef NANORANGE_TYPE_TRAITS_HPP_INCLUDED |
150 | | #define NANORANGE_TYPE_TRAITS_HPP_INCLUDED |
151 | | |
152 | | // nanorange/detail/common_reference.hpp |
153 | | // |
154 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
155 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
156 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
157 | | |
158 | | #ifndef NANORANGE_DETAIL_COMMON_REFERENCE_HPP_INCLUDED |
159 | | #define NANORANGE_DETAIL_COMMON_REFERENCE_HPP_INCLUDED |
160 | | |
161 | | // nanorange/detail/type_traits.hpp |
162 | | // |
163 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
164 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
165 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
166 | | |
167 | | #ifndef NANORANGE_DETAIL_TYPE_TRAITS_HPP_INCLUDED |
168 | | #define NANORANGE_DETAIL_TYPE_TRAITS_HPP_INCLUDED |
169 | | |
170 | | #include <type_traits> |
171 | | |
172 | | NANO_BEGIN_NAMESPACE |
173 | | |
174 | | template <typename T> |
175 | | struct remove_cvref { |
176 | | using type = std::remove_cv_t<std::remove_reference_t<T>>; |
177 | | }; |
178 | | |
179 | | template <typename T> |
180 | | using remove_cvref_t = typename remove_cvref<T>::type; |
181 | | |
182 | | template <typename T> |
183 | | struct type_identity { |
184 | | using type = T; |
185 | | }; |
186 | | |
187 | | template <typename T> |
188 | | using type_identity_t = typename type_identity<T>::type; |
189 | | |
190 | | namespace detail { |
191 | | |
192 | | template <bool> |
193 | | struct conditional { |
194 | | template <typename T, typename> |
195 | | using type = T; |
196 | | }; |
197 | | |
198 | | template <> |
199 | | struct conditional<false> { |
200 | | template <typename, typename U> |
201 | | using type = U; |
202 | | }; |
203 | | |
204 | | template <bool B, typename T, typename U> |
205 | | using conditional_t = typename conditional<B>::template type<T, U>; |
206 | | |
207 | | template <template <class...> class AliasT, typename... Args> |
208 | | auto exists_helper(long) -> std::false_type; |
209 | | |
210 | | template <template <class...> class AliasT, |
211 | | typename... Args, |
212 | | typename = AliasT<Args...>> |
213 | | auto exists_helper(int) -> std::true_type; |
214 | | |
215 | | template <template <class...> class AliasT, typename... Args> |
216 | | inline constexpr bool exists_v = |
217 | | decltype(exists_helper<AliasT, Args...>(0))::value; |
218 | | |
219 | | template <typename, typename...> |
220 | | auto test_requires_fn(long) -> std::false_type; |
221 | | |
222 | | template <typename R, |
223 | | typename... Args, |
224 | | typename = decltype(&R::template requires_<Args...>)> |
225 | | auto test_requires_fn(int) -> std::true_type; |
226 | | |
227 | | template <typename R, typename... Args> |
228 | | inline constexpr bool requires_ = |
229 | | decltype(test_requires_fn<R, Args...>(0))::value; |
230 | | |
231 | | template <bool Expr> |
232 | | using requires_expr = std::enable_if_t<Expr, int>; |
233 | | |
234 | | template <std::size_t I> |
235 | | struct priority_tag : priority_tag<I - 1> {}; |
236 | | |
237 | | template <> |
238 | | struct priority_tag<0> {}; |
239 | | |
240 | | } // namespace detail |
241 | | |
242 | | NANO_END_NAMESPACE |
243 | | |
244 | | #endif |
245 | | |
246 | | NANO_BEGIN_NAMESPACE |
247 | | |
248 | | template <typename...> |
249 | | struct common_type; |
250 | | |
251 | | namespace detail { |
252 | | |
253 | | template <typename T, typename U> |
254 | | struct copy_cv { |
255 | | using type = U; |
256 | | }; |
257 | | |
258 | | template <typename T, typename U> |
259 | | struct copy_cv<const T, U> { |
260 | | using type = std::add_const_t<U>; |
261 | | }; |
262 | | |
263 | | template <typename T, typename U> |
264 | | struct copy_cv<volatile T, U> { |
265 | | using type = std::add_volatile_t<U>; |
266 | | }; |
267 | | |
268 | | template <typename T, typename U> |
269 | | struct copy_cv<const volatile T, U> { |
270 | | using type = std::add_cv_t<U>; |
271 | | }; |
272 | | |
273 | | template <typename T, typename U> |
274 | | using copy_cv_t = typename copy_cv<T, U>::type; |
275 | | |
276 | | template <typename T> |
277 | | using cref_t = |
278 | | std::add_lvalue_reference_t<const std::remove_reference_t<T>>; |
279 | | |
280 | | // Workaround for "term does not evaluate to a function taking 0 arguments" |
281 | | // error in MSVC 19.22 (issue #75) |
282 | | #if defined(_MSC_VER) && _MSC_VER >= 1922 |
283 | | template <typename, typename, typename = void> |
284 | | struct cond_res {}; |
285 | | |
286 | | template <typename T, typename U> |
287 | | struct cond_res<T, |
288 | | U, |
289 | | std::void_t<decltype(false ? std::declval<T (&)()>()() |
290 | | : std::declval<U (&)()>()())>> { |
291 | | using type = decltype(false ? std::declval<T (&)()>()() |
292 | | : std::declval<U (&)()>()()); |
293 | | }; |
294 | | |
295 | | template <typename T, typename U> |
296 | | using cond_res_t = typename cond_res<T, U>::type; |
297 | | #else |
298 | | template <typename T, typename U> |
299 | | using cond_res_t = |
300 | | decltype(false ? std::declval<T (&)()>()() : std::declval<U (&)()>()()); |
301 | | #endif |
302 | | |
303 | | // For some value of "simple" |
304 | | template <typename A, |
305 | | typename B, |
306 | | typename X = std::remove_reference_t<A>, |
307 | | typename Y = std::remove_reference_t<B>, |
308 | | typename = void> |
309 | | struct common_ref {}; |
310 | | |
311 | | template <typename A, typename B> |
312 | | using common_ref_t = typename common_ref<A, B>::type; |
313 | | |
314 | | template <typename A, |
315 | | typename B, |
316 | | typename X = std::remove_reference_t<A>, |
317 | | typename Y = std::remove_reference_t<B>, |
318 | | typename = void> |
319 | | struct lval_common_ref {}; |
320 | | |
321 | | template <typename A, typename B, typename X, typename Y> |
322 | | struct lval_common_ref< |
323 | | A, |
324 | | B, |
325 | | X, |
326 | | Y, |
327 | | std::enable_if_t<std::is_reference_v< |
328 | | cond_res_t<copy_cv_t<X, Y>&, copy_cv_t<Y, X>&>>>> { |
329 | | using type = cond_res_t<copy_cv_t<X, Y>&, copy_cv_t<Y, X>&>; |
330 | | }; |
331 | | |
332 | | template <typename A, typename B> |
333 | | using lval_common_ref_t = typename lval_common_ref<A, B>::type; |
334 | | |
335 | | template <typename A, typename B, typename X, typename Y> |
336 | | struct common_ref<A&, B&, X, Y> : lval_common_ref<A&, B&> {}; |
337 | | |
338 | | template <typename X, typename Y> |
339 | | using rref_cr_helper_t = |
340 | | std::remove_reference_t<lval_common_ref_t<X&, Y&>>&&; |
341 | | |
342 | | template <typename A, typename B, typename X, typename Y> |
343 | | struct common_ref< |
344 | | A&&, |
345 | | B&&, |
346 | | X, |
347 | | Y, |
348 | | std::enable_if_t<std::is_convertible_v<A&&, rref_cr_helper_t<X, Y>> && |
349 | | std::is_convertible_v<B&&, rref_cr_helper_t<X, Y>>>> { |
350 | | using type = rref_cr_helper_t<X, Y>; |
351 | | }; |
352 | | |
353 | | template <typename A, typename B, typename X, typename Y> |
354 | | struct common_ref< |
355 | | A&&, |
356 | | B&, |
357 | | X, |
358 | | Y, |
359 | | std::enable_if_t< |
360 | | std::is_convertible_v<A&&, lval_common_ref_t<const X&, Y&>>>> { |
361 | | using type = lval_common_ref_t<const X&, Y&>; |
362 | | }; |
363 | | |
364 | | template <typename A, typename B, typename X, typename Y> |
365 | | struct common_ref<A&, B&&, X, Y> : common_ref<B&&, A&> {}; |
366 | | |
367 | | template <typename> |
368 | | struct xref { |
369 | | template <typename U> |
370 | | using type = U; |
371 | | }; |
372 | | |
373 | | template <typename A> |
374 | | struct xref<A&> { |
375 | | template <typename U> |
376 | | using type = |
377 | | std::add_lvalue_reference_t<typename xref<A>::template type<U>>; |
378 | | }; |
379 | | |
380 | | template <typename A> |
381 | | struct xref<A&&> { |
382 | | template <typename U> |
383 | | using type = |
384 | | std::add_rvalue_reference_t<typename xref<A>::template type<U>>; |
385 | | }; |
386 | | |
387 | | template <typename A> |
388 | | struct xref<const A> { |
389 | | template <typename U> |
390 | | using type = std::add_const_t<typename xref<A>::template type<U>>; |
391 | | }; |
392 | | |
393 | | template <typename A> |
394 | | struct xref<volatile A> { |
395 | | template <typename U> |
396 | | using type = std::add_volatile_t<typename xref<A>::template type<U>>; |
397 | | }; |
398 | | |
399 | | template <typename A> |
400 | | struct xref<const volatile A> { |
401 | | template <typename U> |
402 | | using type = std::add_cv_t<typename xref<A>::template type<U>>; |
403 | | }; |
404 | | |
405 | | } // namespace detail |
406 | | |
407 | | template <class T, |
408 | | class U, |
409 | | template <class> |
410 | | class TQual, |
411 | | template <class> |
412 | | class UQual> |
413 | | struct basic_common_reference {}; |
414 | | |
415 | | template <typename...> |
416 | | struct common_reference; |
417 | | |
418 | | template <typename... Ts> |
419 | | using common_reference_t = typename common_reference<Ts...>::type; |
420 | | |
421 | | template <> |
422 | | struct common_reference<> {}; |
423 | | |
424 | | template <typename T0> |
425 | | struct common_reference<T0> { |
426 | | using type = T0; |
427 | | }; |
428 | | |
429 | | namespace detail { |
430 | | |
431 | | template <typename T, typename U> |
432 | | inline constexpr bool has_common_ref_v = exists_v<common_ref_t, T, U>; |
433 | | |
434 | | template <typename T, typename U> |
435 | | using basic_common_ref_t = |
436 | | typename basic_common_reference<remove_cvref_t<T>, |
437 | | remove_cvref_t<U>, |
438 | | detail::xref<T>::template type, |
439 | | detail::xref<U>::template type>::type; |
440 | | |
441 | | template <typename T, typename U> |
442 | | inline constexpr bool has_basic_common_ref_v = |
443 | | exists_v<basic_common_ref_t, T, U>; |
444 | | |
445 | | template <typename T, typename U> |
446 | | inline constexpr bool has_cond_res_v = exists_v<cond_res_t, T, U>; |
447 | | |
448 | | template <typename T, typename U, typename = void> |
449 | | struct binary_common_ref : common_type<T, U> {}; |
450 | | |
451 | | template <typename T, typename U> |
452 | | struct binary_common_ref<T, U, std::enable_if_t<has_common_ref_v<T, U>>> |
453 | | : common_ref<T, U> {}; |
454 | | |
455 | | template <typename T, typename U> |
456 | | struct binary_common_ref<T, |
457 | | U, |
458 | | std::enable_if_t<has_basic_common_ref_v<T, U> && |
459 | | !has_common_ref_v<T, U>>> { |
460 | | using type = basic_common_ref_t<T, U>; |
461 | | }; |
462 | | |
463 | | template <typename T, typename U> |
464 | | struct binary_common_ref<T, |
465 | | U, |
466 | | std::enable_if_t<has_cond_res_v<T, U> && |
467 | | !has_basic_common_ref_v<T, U> && |
468 | | !has_common_ref_v<T, U>>> { |
469 | | using type = cond_res_t<T, U>; |
470 | | }; |
471 | | |
472 | | } // namespace detail |
473 | | |
474 | | template <typename T1, typename T2> |
475 | | struct common_reference<T1, T2> : detail::binary_common_ref<T1, T2> {}; |
476 | | |
477 | | namespace detail { |
478 | | |
479 | | template <typename Void, typename T1, typename T2, typename... Rest> |
480 | | struct multiple_common_reference {}; |
481 | | |
482 | | template <typename T1, typename T2, typename... Rest> |
483 | | struct multiple_common_reference<std::void_t<common_reference_t<T1, T2>>, |
484 | | T1, |
485 | | T2, |
486 | | Rest...> |
487 | | : common_reference<common_reference_t<T1, T2>, Rest...> {}; |
488 | | |
489 | | } // namespace detail |
490 | | |
491 | | template <typename T1, typename T2, typename... Rest> |
492 | | struct common_reference<T1, T2, Rest...> |
493 | | : detail::multiple_common_reference<void, T1, T2, Rest...> {}; |
494 | | |
495 | | NANO_END_NAMESPACE |
496 | | |
497 | | #endif |
498 | | |
499 | | // nanorange/detail/common_reference.hpp |
500 | | // |
501 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
502 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
503 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
504 | | |
505 | | #ifndef NANORANGE_DETAIL_COMMON_TYPE_HPP_INCLUDED |
506 | | #define NANORANGE_DETAIL_COMMON_TYPE_HPP_INCLUDED |
507 | | |
508 | | NANO_BEGIN_NAMESPACE |
509 | | |
510 | | template <typename...> |
511 | | struct common_type; |
512 | | |
513 | | template <typename... Ts> |
514 | | using common_type_t = typename common_type<Ts...>::type; |
515 | | |
516 | | namespace detail { |
517 | | |
518 | | template <typename T, typename U> |
519 | | constexpr bool same_decayed_v = std::is_same<T, std::decay_t<T>>::value && |
520 | | std::is_same<U, std::decay_t<U>>::value; |
521 | | |
522 | | template <typename T, typename U> |
523 | | using ternary_return_t = |
524 | | std::decay_t<decltype(false ? std::declval<T>() : std::declval<U>())>; |
525 | | |
526 | | template <typename, typename, typename = void> |
527 | | struct binary_common_type {}; |
528 | | |
529 | | template <typename T, typename U> |
530 | | struct binary_common_type<T, U, std::enable_if_t<!same_decayed_v<T, U>>> |
531 | | : nano::common_type<std::decay_t<T>, std::decay_t<U>> {}; |
532 | | |
533 | | template <typename T, typename U> |
534 | | struct binary_common_type< |
535 | | T, |
536 | | U, |
537 | | std::enable_if_t<same_decayed_v<T, U> && |
538 | | exists_v<ternary_return_t, T, U>>> { |
539 | | using type = ternary_return_t<T, U>; |
540 | | }; |
541 | | |
542 | | template <typename T, typename U> |
543 | | struct binary_common_type< |
544 | | T, |
545 | | U, |
546 | | std::enable_if_t<same_decayed_v<T, U> && |
547 | | !exists_v<ternary_return_t, T, U> && |
548 | | exists_v<cond_res_t, cref_t<T>, cref_t<U>>>> { |
549 | | using type = std::decay_t<cond_res_t<cref_t<T>, cref_t<U>>>; |
550 | | }; |
551 | | |
552 | | } // namespace detail |
553 | | |
554 | | template <> |
555 | | struct common_type<> {}; |
556 | | |
557 | | template <typename T> |
558 | | struct common_type<T> : common_type<T, T> {}; |
559 | | |
560 | | template <typename T, typename U> |
561 | | struct common_type<T, U> : detail::binary_common_type<T, U> {}; |
562 | | |
563 | | namespace detail { |
564 | | |
565 | | template <typename Void, typename...> |
566 | | struct multiple_common_type {}; |
567 | | |
568 | | template <typename T1, typename T2, typename... R> |
569 | | struct multiple_common_type<std::void_t<common_type_t<T1, T2>>, |
570 | | T1, |
571 | | T2, |
572 | | R...> |
573 | | : common_type<common_type_t<T1, T2>, R...> {}; |
574 | | |
575 | | } // namespace detail |
576 | | |
577 | | template <typename T1, typename T2, typename... R> |
578 | | struct common_type<T1, T2, R...> |
579 | | : detail::multiple_common_type<void, T1, T2, R...> {}; |
580 | | |
581 | | NANO_END_NAMESPACE |
582 | | |
583 | | #endif |
584 | | |
585 | | #endif |
586 | | |
587 | | #include <utility> |
588 | | |
589 | | NANO_BEGIN_NAMESPACE |
590 | | |
591 | | // [concept.same] |
592 | | template <typename T, typename U> |
593 | | NANO_CONCEPT same_as = std::is_same_v<T, U>; |
594 | | |
595 | | // [concept.derived] |
596 | | namespace detail { |
597 | | |
598 | | struct derived_from_concept { |
599 | | template <typename, typename> |
600 | | static auto test(long) -> std::false_type; |
601 | | |
602 | | template <typename Derived, typename Base> |
603 | | static auto test(int) -> std::enable_if_t< |
604 | | std::is_base_of_v<Base, Derived> && |
605 | | std::is_convertible_v<const volatile Derived*, |
606 | | const volatile Base*>, |
607 | | std::true_type>; |
608 | | }; |
609 | | |
610 | | } // namespace detail |
611 | | |
612 | | template <typename Derived, typename Base> |
613 | | NANO_CONCEPT derived_from = |
614 | | decltype(detail::derived_from_concept::test<Derived, Base>(0))::value; |
615 | | |
616 | | // [concept.convertible] |
617 | | namespace detail { |
618 | | |
619 | | struct convertible_to_concept { |
620 | | template <typename From, typename To> |
621 | | auto requires_(std::add_rvalue_reference_t<From> (&f)()) |
622 | | -> decltype(static_cast<To>(f())); |
623 | | }; |
624 | | |
625 | | } // namespace detail |
626 | | |
627 | | template <typename From, typename To> |
628 | | NANO_CONCEPT convertible_to = |
629 | | std::is_convertible_v<From, To> && |
630 | | detail::requires_<detail::convertible_to_concept, From, To>; |
631 | | |
632 | | // [concept.commonref] |
633 | | namespace detail { |
634 | | |
635 | | struct common_reference_with_concept { |
636 | | template <typename T, typename U> |
637 | | static auto test(long) -> std::false_type; |
638 | | |
639 | | template <typename T, typename U> |
640 | | static auto test(int) -> std::enable_if_t< |
641 | | same_as<common_reference_t<T, U>, common_reference_t<U, T>> && |
642 | | convertible_to<T, common_reference_t<T, U>> && |
643 | | convertible_to<U, common_reference_t<T, U>>, |
644 | | std::true_type>; |
645 | | }; |
646 | | |
647 | | } // namespace detail |
648 | | |
649 | | template <typename T, typename U> |
650 | | NANO_CONCEPT common_reference_with = |
651 | | decltype(detail::common_reference_with_concept::test<T, U>(0))::value; |
652 | | |
653 | | // [concepts.common] |
654 | | namespace detail { |
655 | | |
656 | | struct common_with_concept { |
657 | | template <typename T, typename U> |
658 | | auto requires_() |
659 | | -> decltype(static_cast<common_type_t<T, U>>(std::declval<T>()), |
660 | | static_cast<common_type_t<T, U>>(std::declval<U>())); |
661 | | |
662 | | template <typename, typename> |
663 | | static auto test(long) -> std::false_type; |
664 | | |
665 | | template <typename T, typename U> |
666 | | static auto test(int) -> std::enable_if_t< |
667 | | same_as<common_type_t<T, U>, common_type_t<U, T>> && |
668 | | detail::requires_<common_with_concept, T, U> && |
669 | | common_reference_with<std::add_lvalue_reference_t<const T>, |
670 | | std::add_lvalue_reference_t<const U>> && |
671 | | common_reference_with< |
672 | | std::add_lvalue_reference_t<common_type_t<T, U>>, |
673 | | common_reference_t<std::add_lvalue_reference_t<const T>, |
674 | | std::add_lvalue_reference_t<const U>>>, |
675 | | std::true_type>; |
676 | | }; |
677 | | |
678 | | } // namespace detail |
679 | | |
680 | | template <typename T, typename U> |
681 | | NANO_CONCEPT common_with = |
682 | | decltype(detail::common_with_concept::test<T, U>(0))::value; |
683 | | |
684 | | // [concept.arithmetic] |
685 | | template <typename T> |
686 | | NANO_CONCEPT integral = std::is_integral_v<T>; |
687 | | |
688 | | template <typename T> |
689 | | NANO_CONCEPT signed_integral = integral<T> && std::is_signed_v<T>; |
690 | | |
691 | | template <typename T> |
692 | | NANO_CONCEPT unsigned_integral = integral<T> && !signed_integral<T>; |
693 | | |
694 | | template <typename T> |
695 | | NANO_CONCEPT floating_point = std::is_floating_point_v<T>; |
696 | | |
697 | | // [concept.assignable] |
698 | | |
699 | | namespace detail { |
700 | | |
701 | | struct assignable_from_concept { |
702 | | template <typename LHS, typename RHS> |
703 | | auto requires_(LHS lhs, RHS&& rhs) |
704 | | -> decltype(requires_expr< |
705 | | same_as<decltype(lhs = std::forward<RHS>(rhs)), |
706 | | LHS>>{}); |
707 | | |
708 | | template <typename, typename> |
709 | | static auto test(long) -> std::false_type; |
710 | | |
711 | | template <typename LHS, typename RHS> |
712 | | static auto test(int) -> std::enable_if_t< |
713 | | std::is_lvalue_reference_v<LHS> && |
714 | | common_reference_with<const std::remove_reference_t<LHS>&, |
715 | | const std::remove_reference_t<RHS>&> && |
716 | | detail::requires_<assignable_from_concept, LHS, RHS>, |
717 | | std::true_type>; |
718 | | }; |
719 | | |
720 | | } // namespace detail |
721 | | |
722 | | template <typename LHS, typename RHS> |
723 | | NANO_CONCEPT assignable_from = |
724 | | decltype(detail::assignable_from_concept::test<LHS, RHS>(0))::value; |
725 | | |
726 | | // [concept.destructible] |
727 | | template <typename T> |
728 | | NANO_CONCEPT destructible = std::is_nothrow_destructible_v<T>; |
729 | | |
730 | | // [concept.constructible] |
731 | | template <typename T, typename... Args> |
732 | | NANO_CONCEPT constructible_from = |
733 | | destructible<T> && std::is_constructible_v<T, Args...>; |
734 | | |
735 | | // [concept.default.init] |
736 | | namespace detail { |
737 | | |
738 | | template <typename, typename = void> |
739 | | inline constexpr bool is_default_initializable = false; |
740 | | |
741 | | // Thanks to Damian Jarek on Slack for this formulation |
742 | | template <typename T> |
743 | | inline constexpr bool |
744 | | is_default_initializable<T, std::void_t<decltype(::new T)>> = true; |
745 | | |
746 | | struct default_initializable_concept { |
747 | | template <typename T, typename = decltype(T{})> |
748 | | auto requires_() -> void; |
749 | | }; |
750 | | |
751 | | } // namespace detail |
752 | | |
753 | | template <typename T> |
754 | | NANO_CONCEPT default_initializable = |
755 | | constructible_from<T> && |
756 | | detail::requires_<detail::default_initializable_concept, T> && |
757 | | detail::is_default_initializable<T>; |
758 | | |
759 | | // [concept.moveconstructible] |
760 | | template <typename T> |
761 | | NANO_CONCEPT move_constructible = |
762 | | constructible_from<T, T> && convertible_to<T, T>; |
763 | | |
764 | | // [concept.copyconstructible] |
765 | | namespace detail { |
766 | | |
767 | | struct copy_constructible_concept { |
768 | | template <typename> |
769 | | static auto test(long) -> std::false_type; |
770 | | |
771 | | template <typename T> |
772 | | static auto test(int) -> std::enable_if_t< |
773 | | move_constructible<T> && constructible_from<T, T&> && |
774 | | convertible_to<T&, T> && constructible_from<T, const T&> && |
775 | | convertible_to<const T&, T> && constructible_from<T, const T> && |
776 | | convertible_to<const T, T>, |
777 | | std::true_type>; |
778 | | }; |
779 | | |
780 | | } // namespace detail |
781 | | |
782 | | template <typename T> |
783 | | NANO_CONCEPT copy_constructible = |
784 | | decltype(detail::copy_constructible_concept::test<T>(0))::value; |
785 | | |
786 | | NANO_END_NAMESPACE |
787 | | |
788 | | #endif |
789 | | |
790 | | // nanorange/detail/concepts/swappable.hpp |
791 | | // |
792 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
793 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
794 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
795 | | |
796 | | #ifndef NANORANGE_DETAIL_CONCEPTS_SWAPPABLE_HPP_INCLUDED |
797 | | #define NANORANGE_DETAIL_CONCEPTS_SWAPPABLE_HPP_INCLUDED |
798 | | |
799 | | // nanorange/detail/swap.hpp |
800 | | // |
801 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
802 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
803 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
804 | | |
805 | | #ifndef NANORANGE_DETAIL_SWAP_HPP_INCLUDED |
806 | | #define NANORANGE_DETAIL_SWAP_HPP_INCLUDED |
807 | | |
808 | | NANO_BEGIN_NAMESPACE |
809 | | |
810 | | // [range.swap] |
811 | | |
812 | | namespace detail { |
813 | | namespace swap_ { |
814 | | |
815 | | template <typename T> |
816 | | void swap(T&, T&) = delete; |
817 | | |
818 | | template <typename T, std::size_t N> |
819 | | void swap(T (&)[N], T (&)[N]) = delete; |
820 | | |
821 | | struct fn { |
822 | | private: |
823 | | template <typename T, typename U> |
824 | | static constexpr auto impl(T&& t, U&& u, priority_tag<2>) noexcept( |
825 | | noexcept(swap(std::forward<T>(t), std::forward<U>(u)))) |
826 | | -> decltype(static_cast<void>(swap(std::forward<T>(t), |
827 | | std::forward<U>(u)))) |
828 | 83.5k | { |
829 | 83.5k | (void)swap(std::forward<T>(t), std::forward<U>(u)); |
830 | 83.5k | } |
831 | | |
832 | | template <typename T, typename U, std::size_t N, typename F = fn> |
833 | | static constexpr auto impl( |
834 | | T (&t)[N], |
835 | | U (&u)[N], |
836 | | priority_tag<1>) noexcept(noexcept(std::declval<F&>()(*t, *u))) |
837 | | -> decltype(std::declval<F&>()(*t, *u)) |
838 | | { |
839 | | for (std::size_t i = 0; i < N; ++i) { |
840 | | fn::impl(t[i], u[i], priority_tag<2>{}); |
841 | | } |
842 | | } |
843 | | |
844 | | template <typename T> |
845 | | static constexpr auto impl(T& a, T& b, priority_tag<0>) noexcept( |
846 | | std::is_nothrow_move_constructible<T>::value&& |
847 | | std::is_nothrow_assignable<T&, T>::value) |
848 | | -> std::enable_if_t<move_constructible<T> && |
849 | | assignable_from<T&, T>> |
850 | | { |
851 | | T temp = std::move(a); |
852 | | a = std::move(b); |
853 | | b = std::move(temp); |
854 | | } |
855 | | |
856 | | public: |
857 | | template <typename T, typename U> |
858 | | constexpr auto operator()(T&& t, U&& u) const |
859 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
860 | | std::forward<U>(u), |
861 | | priority_tag<2>{}))) |
862 | | -> decltype(fn::impl(std::forward<T>(t), |
863 | | std::forward<U>(u), |
864 | | priority_tag<2>{})) |
865 | 83.5k | { |
866 | 83.5k | return fn::impl(std::forward<T>(t), std::forward<U>(u), |
867 | 83.5k | priority_tag<2>{}); |
868 | 83.5k | } |
869 | | }; |
870 | | |
871 | | } // end namespace swap_ |
872 | | } // end namespace detail |
873 | | |
874 | | NANO_INLINE_VAR(detail::swap_::fn, swap) |
875 | | |
876 | | NANO_END_NAMESPACE |
877 | | |
878 | | #endif |
879 | | |
880 | | NANO_BEGIN_NAMESPACE |
881 | | |
882 | | // [concept.swappable] |
883 | | namespace detail { |
884 | | |
885 | | struct swappable_concept { |
886 | | template <typename T> |
887 | | auto requires_(T& a, T& b) -> decltype(ranges::swap(a, b)); |
888 | | }; |
889 | | |
890 | | } // namespace detail |
891 | | |
892 | | template <typename T> |
893 | | NANO_CONCEPT swappable = detail::requires_<detail::swappable_concept, T>; |
894 | | |
895 | | namespace detail { |
896 | | |
897 | | struct swappable_with_concept { |
898 | | template <typename T, typename U> |
899 | | auto requires_(T&& t, U&& u) |
900 | | -> decltype(ranges::swap(std::forward<T>(t), std::forward<T>(t)), |
901 | | ranges::swap(std::forward<U>(u), std::forward<U>(u)), |
902 | | ranges::swap(std::forward<T>(t), std::forward<U>(u)), |
903 | | ranges::swap(std::forward<U>(u), std::forward<T>(t))); |
904 | | |
905 | | template <typename, typename> |
906 | | static auto test(long) -> std::false_type; |
907 | | |
908 | | template <typename T, typename U> |
909 | | static auto test(int) -> std::enable_if_t< |
910 | | common_reference_with<const std::remove_reference_t<T>&, |
911 | | const std::remove_reference_t<U>&> && |
912 | | detail::requires_<swappable_with_concept, T, U>, |
913 | | std::true_type>; |
914 | | }; |
915 | | |
916 | | } // namespace detail |
917 | | |
918 | | template <typename T, typename U> |
919 | | NANO_CONCEPT swappable_with = |
920 | | decltype(detail::swappable_with_concept::test<T, U>(0))::value; |
921 | | |
922 | | NANO_END_NAMESPACE |
923 | | |
924 | | #endif |
925 | | |
926 | | NANO_BEGIN_NAMESPACE |
927 | | |
928 | | // [concept.boolean_testable] |
929 | | namespace detail { |
930 | | |
931 | | template <typename T> |
932 | | NANO_CONCEPT boolean_testable_impl = convertible_to<T, bool>; |
933 | | |
934 | | struct boolean_testable_concept { |
935 | | template <typename T> |
936 | | auto requires_(T&& t) -> requires_expr< |
937 | | boolean_testable_impl<decltype(!std::forward<T>(t))>>; |
938 | | }; |
939 | | |
940 | | template <typename T> |
941 | | NANO_CONCEPT boolean_testable = |
942 | | boolean_testable_impl<T> && |
943 | | detail::requires_<boolean_testable_concept, T>; |
944 | | |
945 | | } // namespace detail |
946 | | |
947 | | // [concept.equalitycomparable] |
948 | | namespace detail { |
949 | | |
950 | | struct weakly_equality_comparable_with_concept { |
951 | | template <typename T, typename U> |
952 | | auto requires_(const std::remove_reference_t<T>& t, |
953 | | const std::remove_reference_t<U>& u) |
954 | | -> decltype(requires_expr<boolean_testable<decltype(t == u)>>{}, |
955 | | requires_expr<boolean_testable<decltype(t != u)>>{}, |
956 | | requires_expr<boolean_testable<decltype(u == t)>>{}, |
957 | | requires_expr<boolean_testable<decltype(u != t)>>{}); |
958 | | }; |
959 | | |
960 | | template <typename T, typename U> |
961 | | NANO_CONCEPT weakly_equality_comparable_with = |
962 | | requires_<weakly_equality_comparable_with_concept, T, U>; |
963 | | |
964 | | } // namespace detail |
965 | | |
966 | | template <typename T> |
967 | | NANO_CONCEPT equality_comparable = |
968 | | detail::weakly_equality_comparable_with<T, T>; |
969 | | |
970 | | namespace detail { |
971 | | |
972 | | struct equality_comparable_with_concept { |
973 | | template <typename, typename> |
974 | | static auto test(long) -> std::false_type; |
975 | | |
976 | | template <typename T, typename U> |
977 | | static auto test(int) -> std::enable_if_t< |
978 | | equality_comparable<T> && equality_comparable<U> && |
979 | | common_reference_with<const std::remove_reference_t<T>&, |
980 | | const std::remove_reference_t<U>&> && |
981 | | equality_comparable< |
982 | | common_reference_t<const std::remove_reference_t<T>&, |
983 | | const std::remove_reference_t<U>&>> && |
984 | | weakly_equality_comparable_with<T, U>, |
985 | | std::true_type>; |
986 | | }; |
987 | | |
988 | | } // namespace detail |
989 | | |
990 | | template <typename T, typename U> |
991 | | NANO_CONCEPT equality_comparable_with = |
992 | | decltype(detail::equality_comparable_with_concept::test<T, U>(0))::value; |
993 | | |
994 | | // [concepts.totallyordered] |
995 | | namespace detail { |
996 | | |
997 | | struct partially_ordered_with_concept { |
998 | | template <typename T, typename U> |
999 | | auto requires_(const std::remove_reference_t<T>& t, |
1000 | | const std::remove_reference_t<U>& u) |
1001 | | -> decltype(requires_expr<boolean_testable<decltype(t < u)>>{}, |
1002 | | requires_expr<boolean_testable<decltype(t > u)>>{}, |
1003 | | requires_expr<boolean_testable<decltype(t <= u)>>{}, |
1004 | | requires_expr<boolean_testable<decltype(t >= u)>>{}, |
1005 | | requires_expr<boolean_testable<decltype(u < t)>>{}, |
1006 | | requires_expr<boolean_testable<decltype(u > t)>>{}, |
1007 | | requires_expr<boolean_testable<decltype(u <= t)>>{}, |
1008 | | requires_expr<boolean_testable<decltype(u >= t)>>{}); |
1009 | | }; |
1010 | | |
1011 | | template <typename T, typename U> |
1012 | | NANO_CONCEPT partially_ordered_with = |
1013 | | detail::requires_<detail::partially_ordered_with_concept, T, U>; |
1014 | | |
1015 | | } // namespace detail |
1016 | | |
1017 | | template <typename T> |
1018 | | NANO_CONCEPT totally_ordered = |
1019 | | equality_comparable<T> && detail::partially_ordered_with<T, T>; |
1020 | | |
1021 | | namespace detail { |
1022 | | |
1023 | | struct totally_ordered_with_concept { |
1024 | | template <typename, typename> |
1025 | | static auto test(long) -> std::false_type; |
1026 | | |
1027 | | template <typename T, typename U> |
1028 | | static auto test(int) |
1029 | | -> std::enable_if_t<totally_ordered<T> && totally_ordered<U> && |
1030 | | equality_comparable_with<T, U> && |
1031 | | totally_ordered<common_reference_t< |
1032 | | const std::remove_reference_t<T>&, |
1033 | | const std::remove_reference_t<U>&>> && |
1034 | | partially_ordered_with<T, U>, |
1035 | | std::true_type>; |
1036 | | }; |
1037 | | |
1038 | | } // namespace detail |
1039 | | |
1040 | | template <typename T, typename U> |
1041 | | NANO_CONCEPT totally_ordered_with = |
1042 | | decltype(detail::totally_ordered_with_concept::test<T, U>(0))::value; |
1043 | | |
1044 | | NANO_END_NAMESPACE |
1045 | | |
1046 | | #endif |
1047 | | |
1048 | | #include <functional> |
1049 | | #include <utility> |
1050 | | |
1051 | | NANO_BEGIN_NAMESPACE |
1052 | | |
1053 | | // [range.comparisons] |
1054 | | |
1055 | | struct equal_to { |
1056 | | template <typename T, typename U> |
1057 | | constexpr auto operator()(T&& t, U&& u) const |
1058 | | -> std::enable_if_t<equality_comparable_with<T, U>, bool> |
1059 | | { |
1060 | | return std::equal_to<>{}(std::forward<T>(t), std::forward<U>(u)); |
1061 | | } |
1062 | | |
1063 | | using is_transparent = std::true_type; |
1064 | | }; |
1065 | | |
1066 | | struct not_equal_to { |
1067 | | template <typename T, typename U> |
1068 | | constexpr auto operator()(T&& t, U&& u) const |
1069 | | -> std::enable_if_t<equality_comparable_with<T, U>, bool> |
1070 | | { |
1071 | | return !ranges::equal_to{}(std::forward<T>(t), std::forward<U>(u)); |
1072 | | } |
1073 | | |
1074 | | using is_transparent = std::true_type; |
1075 | | }; |
1076 | | |
1077 | | struct less { |
1078 | | template <typename T, typename U> |
1079 | | constexpr auto operator()(T&& t, U&& u) const |
1080 | | -> std::enable_if_t<totally_ordered_with<T, U>, bool> |
1081 | 915k | { |
1082 | 915k | return std::less<>{}(std::forward<T>(t), std::forward<U>(u)); |
1083 | 915k | } Unexecuted instantiation: std::__1::enable_if<totally_ordered_with<int const&, int const&>, bool>::type nano::ranges::less::operator()<int const&, int const&>(int const&, int const&) const std::__1::enable_if<totally_ordered_with<std::__1::pair<char32_t, char32_t>&, std::__1::pair<char32_t, char32_t>&>, bool>::type nano::ranges::less::operator()<std::__1::pair<char32_t, char32_t>&, std::__1::pair<char32_t, char32_t>&>(std::__1::pair<char32_t, char32_t>&, std::__1::pair<char32_t, char32_t>&) const Line | Count | Source | 1081 | 915k | { | 1082 | 915k | return std::less<>{}(std::forward<T>(t), std::forward<U>(u)); | 1083 | 915k | } |
|
1084 | | |
1085 | | using is_transparent = std::true_type; |
1086 | | }; |
1087 | | |
1088 | | struct greater { |
1089 | | template <typename T, typename U> |
1090 | | constexpr auto operator()(T&& t, U&& u) const |
1091 | | -> std::enable_if_t<totally_ordered_with<T, U>, bool> |
1092 | | { |
1093 | | return ranges::less{}(std::forward<U>(u), std::forward<T>(t)); |
1094 | | } |
1095 | | |
1096 | | using is_transparent = std::true_type; |
1097 | | }; |
1098 | | |
1099 | | struct greater_equal { |
1100 | | template <typename T, typename U> |
1101 | | constexpr auto operator()(T&& t, U&& u) const |
1102 | | -> std::enable_if_t<totally_ordered_with<T, U>, bool> |
1103 | | { |
1104 | | return !ranges::less{}(std::forward<T>(t), std::forward<U>(u)); |
1105 | | } |
1106 | | |
1107 | | using is_transparent = std::true_type; |
1108 | | }; |
1109 | | |
1110 | | struct less_equal { |
1111 | | template <typename T, typename U> |
1112 | | constexpr auto operator()(T&& t, U&& u) const |
1113 | | -> std::enable_if_t<totally_ordered_with<T, U>, bool> |
1114 | | { |
1115 | | return !ranges::less{}(std::forward<U>(u), std::forward<T>(t)); |
1116 | | } |
1117 | | |
1118 | | using is_transparent = std::true_type; |
1119 | | }; |
1120 | | |
1121 | | NANO_END_NAMESPACE |
1122 | | |
1123 | | #endif |
1124 | | // nanorange/detail/functional/identity.hpp |
1125 | | // |
1126 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1127 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1128 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1129 | | |
1130 | | #ifndef NANORANGE_DETAIL_FUNCTIONAL_IDENTITY_HPP_INCLUDED |
1131 | | #define NANORANGE_DETAIL_FUNCTIONAL_IDENTITY_HPP_INCLUDED |
1132 | | |
1133 | | #include <type_traits> |
1134 | | #include <utility> |
1135 | | |
1136 | | NANO_BEGIN_NAMESPACE |
1137 | | |
1138 | | struct identity { |
1139 | | template <typename T> |
1140 | | constexpr T&& operator()(T&& t) const noexcept |
1141 | 74.6M | { |
1142 | 74.6M | return std::forward<T>(t); |
1143 | 74.6M | } Unexecuted instantiation: int const& nano::ranges::identity::operator()<int const&>(int const&) const char const& nano::ranges::identity::operator()<char const&>(char const&) const Line | Count | Source | 1141 | 60.3M | { | 1142 | 60.3M | return std::forward<T>(t); | 1143 | 60.3M | } |
Unexecuted instantiation: char& nano::ranges::identity::operator()<char&>(char&) const char&& nano::ranges::identity::operator()<char>(char&&) const Line | Count | Source | 1141 | 271k | { | 1142 | 271k | return std::forward<T>(t); | 1143 | 271k | } |
std::__1::pair<char32_t, char32_t>& nano::ranges::identity::operator()<std::__1::pair<char32_t, char32_t>&>(std::__1::pair<char32_t, char32_t>&) const Line | Count | Source | 1141 | 1.83M | { | 1142 | 1.83M | return std::forward<T>(t); | 1143 | 1.83M | } |
std::__1::pair<char32_t, char32_t> const& nano::ranges::identity::operator()<std::__1::pair<char32_t, char32_t> const&>(std::__1::pair<char32_t, char32_t> const&) const Line | Count | Source | 1141 | 5.77M | { | 1142 | 5.77M | return std::forward<T>(t); | 1143 | 5.77M | } |
Unexecuted instantiation: std::__1::sub_match<char const*> const& nano::ranges::identity::operator()<std::__1::sub_match<char const*> const&>(std::__1::sub_match<char const*> const&) const wchar_t const& nano::ranges::identity::operator()<wchar_t const&>(wchar_t const&) const Line | Count | Source | 1141 | 5.89M | { | 1142 | 5.89M | return std::forward<T>(t); | 1143 | 5.89M | } |
Unexecuted instantiation: wchar_t& nano::ranges::identity::operator()<wchar_t&>(wchar_t&) const Unexecuted instantiation: std::__1::sub_match<wchar_t const*> const& nano::ranges::identity::operator()<std::__1::sub_match<wchar_t const*> const&>(std::__1::sub_match<wchar_t const*> const&) const wchar_t&& nano::ranges::identity::operator()<wchar_t>(wchar_t&&) const Line | Count | Source | 1141 | 484k | { | 1142 | 484k | return std::forward<T>(t); | 1143 | 484k | } |
|
1144 | | |
1145 | | using is_transparent = std::true_type; |
1146 | | }; |
1147 | | |
1148 | | NANO_END_NAMESPACE |
1149 | | |
1150 | | #endif |
1151 | | |
1152 | | // nanorange/detail/iterator/indirect_callable_concepts.hpp |
1153 | | // |
1154 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1155 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1156 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1157 | | |
1158 | | #ifndef NANORANGE_DETAIL_ITERATOR_INDIRECT_CALLABLE_CONCEPTS_HPP_INCLUDED |
1159 | | #define NANORANGE_DETAIL_ITERATOR_INDIRECT_CALLABLE_CONCEPTS_HPP_INCLUDED |
1160 | | |
1161 | | // nanorange/detail/iterator/concepts.hpp |
1162 | | // |
1163 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1164 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1165 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1166 | | |
1167 | | #ifndef NANORANGE_DETAIL_ITERATOR_CONCEPTS_HPP_INCLUDED |
1168 | | #define NANORANGE_DETAIL_ITERATOR_CONCEPTS_HPP_INCLUDED |
1169 | | |
1170 | | // nanorange/detail/concepts/object.hpp |
1171 | | // |
1172 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1173 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1174 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1175 | | |
1176 | | #ifndef NANORANGE_DETAIL_CONCEPTS_OBJECT_HPP_INCLUDED |
1177 | | #define NANORANGE_DETAIL_CONCEPTS_OBJECT_HPP_INCLUDED |
1178 | | |
1179 | | // nanorange/detail/functional/invoke.hpp |
1180 | | // |
1181 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1182 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1183 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1184 | | |
1185 | | #ifndef NANORANGE_DETAIL_FUNCTIONAL_INVOKE_HPP_INCLUDED |
1186 | | #define NANORANGE_DETAIL_FUNCTIONAL_INVOKE_HPP_INCLUDED |
1187 | | |
1188 | | #include <functional> |
1189 | | |
1190 | | NANO_BEGIN_NAMESPACE |
1191 | | |
1192 | | namespace detail { |
1193 | | |
1194 | | // This is a reimplementation of std::invoke, which for some stupid |
1195 | | // reason is not constexpr in C++17 |
1196 | | inline namespace invoke_ { |
1197 | | |
1198 | | template <typename> |
1199 | | constexpr bool is_reference_wrapper_v = false; |
1200 | | |
1201 | | template <typename T> |
1202 | | constexpr bool is_reference_wrapper_v<std::reference_wrapper<T>> = true; |
1203 | | |
1204 | | struct fn { |
1205 | | private: |
1206 | | template <class Base, class T, class Derived, class... Args> |
1207 | | static constexpr auto |
1208 | | impl(T Base::*pmf, Derived&& ref, Args&&... args) noexcept(noexcept( |
1209 | | (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))) |
1210 | | -> std::enable_if_t< |
1211 | | std::is_function<T>::value && |
1212 | | std::is_base_of<Base, std::decay_t<Derived>>::value, |
1213 | | decltype((std::forward<Derived>(ref).* |
1214 | | pmf)(std::forward<Args>(args)...))> |
1215 | | { |
1216 | | return (std::forward<Derived>(ref).* |
1217 | | pmf)(std::forward<Args>(args)...); |
1218 | | } |
1219 | | |
1220 | | template <class Base, class T, class RefWrap, class... Args> |
1221 | | static constexpr auto |
1222 | | impl(T Base::*pmf, RefWrap&& ref, Args&&... args) noexcept( |
1223 | | noexcept((ref.get().*pmf)(std::forward<Args>(args)...))) |
1224 | | -> std::enable_if_t< |
1225 | | std::is_function<T>::value && |
1226 | | is_reference_wrapper_v<std::decay_t<RefWrap>>, |
1227 | | decltype((ref.get().*pmf)(std::forward<Args>(args)...))> |
1228 | | { |
1229 | | return (ref.get().*pmf)(std::forward<Args>(args)...); |
1230 | | } |
1231 | | |
1232 | | template <class Base, class T, class Pointer, class... Args> |
1233 | | static constexpr auto |
1234 | | impl(T Base::*pmf, Pointer&& ptr, Args&&... args) noexcept( |
1235 | | noexcept(((*std::forward<Pointer>(ptr)).* |
1236 | | pmf)(std::forward<Args>(args)...))) |
1237 | | -> std::enable_if_t< |
1238 | | std::is_function<T>::value && |
1239 | | !is_reference_wrapper_v<std::decay_t<Pointer>> && |
1240 | | !std::is_base_of<Base, std::decay_t<Pointer>>::value, |
1241 | | decltype(((*std::forward<Pointer>(ptr)).* |
1242 | | pmf)(std::forward<Args>(args)...))> |
1243 | | { |
1244 | | return ((*std::forward<Pointer>(ptr)).* |
1245 | | pmf)(std::forward<Args>(args)...); |
1246 | | } |
1247 | | |
1248 | | template <class Base, class T, class Derived> |
1249 | | static constexpr auto impl(T Base::*pmd, Derived&& ref) noexcept( |
1250 | | noexcept(std::forward<Derived>(ref).*pmd)) |
1251 | | -> std::enable_if_t< |
1252 | | !std::is_function<T>::value && |
1253 | | std::is_base_of<Base, std::decay_t<Derived>>::value, |
1254 | | decltype(std::forward<Derived>(ref).*pmd)> |
1255 | | { |
1256 | | return std::forward<Derived>(ref).*pmd; |
1257 | | } |
1258 | | |
1259 | | template <class Base, class T, class RefWrap> |
1260 | | static constexpr auto impl(T Base::*pmd, RefWrap&& ref) noexcept( |
1261 | | noexcept(ref.get().*pmd)) |
1262 | | -> std::enable_if_t< |
1263 | | !std::is_function<T>::value && |
1264 | | is_reference_wrapper_v<std::decay_t<RefWrap>>, |
1265 | | decltype(ref.get().*pmd)> |
1266 | | { |
1267 | | return ref.get().*pmd; |
1268 | | } |
1269 | | |
1270 | | template <class Base, class T, class Pointer> |
1271 | | static constexpr auto impl(T Base::*pmd, Pointer&& ptr) noexcept( |
1272 | | noexcept((*std::forward<Pointer>(ptr)).*pmd)) |
1273 | | -> std::enable_if_t< |
1274 | | !std::is_function<T>::value && |
1275 | | !is_reference_wrapper_v<std::decay_t<Pointer>> && |
1276 | | !std::is_base_of<Base, std::decay_t<Pointer>>::value, |
1277 | | decltype((*std::forward<Pointer>(ptr)).*pmd)> |
1278 | | { |
1279 | | return (*std::forward<Pointer>(ptr)).*pmd; |
1280 | | } |
1281 | | |
1282 | | template <class F, class... Args> |
1283 | | static constexpr auto impl(F&& f, Args&&... args) noexcept( |
1284 | | noexcept(std::forward<F>(f)(std::forward<Args>(args)...))) |
1285 | | -> std::enable_if_t< |
1286 | | !std::is_member_pointer<std::decay_t<F>>::value, |
1287 | | decltype(std::forward<F>(f)(std::forward<Args>(args)...))> |
1288 | 148M | { |
1289 | 148M | return std::forward<F>(f)(std::forward<Args>(args)...); |
1290 | 148M | } Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKiEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSD_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_4lessEJRKiS8_EEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSD_ _ZN4nano6ranges6detail7invoke_2fn4implIRN3scn2v24impl12function_refIFbcES9_EEJRKcEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISG_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSG_DpOSI_ Line | Count | Source | 1288 | 7.36M | { | 1289 | 7.36M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 7.36M | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKcEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSD_ Line | Count | Source | 1288 | 60.3M | { | 1289 | 60.3M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 60.3M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRKZNKS1_7find_fnclIRNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEcNS0_8identityEEENS7_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SF_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSH_EEEENS1_16projected_helperISP_SK_vEEEEPKT0_EENSJ_IX14borrowed_rangeISH_EEE4typeISP_NS0_8danglingEEEE4typeEOSH_RSU_SK_EUlRKSH_E_JRcEEENSG_IXntsr3std17is_member_pointerIu7__decayISH_EEE5valueEDTclclsr3stdE7forwardISH_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeES12_DpOS1B_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRcEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISA_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSA_DpOSC_ _ZN4nano6ranges6detail7invoke_2fn4implIRN3scn2v24impl12function_refIFbcES9_EEJcEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISE_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSE_DpOSG_ Line | Count | Source | 1288 | 271k | { | 1289 | 271k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 271k | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJcEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardIS9_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOS9_DpOSB_ Line | Count | Source | 1288 | 271k | { | 1289 | 271k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 271k | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_4lessEJRNSt3__14pairIDiDiEESA_EEENS7_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISC_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSC_DpOSE_ Line | Count | Source | 1288 | 915k | { | 1289 | 915k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 915k | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRNSt3__14pairIDiDiEEEEENS7_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISC_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSC_DpOSE_ Line | Count | Source | 1288 | 1.83M | { | 1289 | 1.83M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 1.83M | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRZNK3scn2v24impl25character_set_reader_implIcE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_JRKNSt3__14pairIDiDiEEEEENSG_9enable_ifIXntsr3std17is_member_pointerIu7__decayISB_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSN_ Line | Count | Source | 1288 | 999k | { | 1289 | 999k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 999k | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKNSt3__14pairIDiDiEEEEENS7_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISD_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSD_DpOSF_ Line | Count | Source | 1288 | 5.77M | { | 1289 | 5.77M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 5.77M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl23read_regex_matches_implIcNSt3__117basic_string_viewIcNS9_11char_traitsIcEEEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSA_IT_NSB_ISK_EEEENS6_6detail11regex_flagsESG_RNS6_19basic_regex_matchesISK_EEEUlOSK_E_JRKNS9_9sub_matchIPKcEEEEENS9_9enable_ifIXntsr3std17is_member_pointerIu7__decayISK_EEE5valueEDTclclsr3stdE7forwardISK_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeESS_DpOS13_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKNSt3__19sub_matchIPKcEEEEENS7_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISF_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSF_DpOSH_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl23read_regex_matches_implIcNS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSt3__117basic_string_viewIT_NSL_11char_traitsISN_EEEENS6_6detail11regex_flagsESH_RNS6_19basic_regex_matchesISN_EEEUlOSN_E_JRKNSL_9sub_matchISC_EEEEENSL_9enable_ifIXntsr3std17is_member_pointerIu7__decayISN_EEE5valueEDTclclsr3stdE7forwardISN_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeESW_DpOS15_ _ZN4nano6ranges6detail7invoke_2fn4implIRN3scn2v24impl12function_refIFbwES9_EEJRKwEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISG_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSG_DpOSI_ Line | Count | Source | 1288 | 5.89M | { | 1289 | 5.89M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 5.89M | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKwEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSD_ Line | Count | Source | 1288 | 5.89M | { | 1289 | 5.89M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 5.89M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRKZNKS1_7find_fnclIRNSt3__112basic_stringIwNS7_11char_traitsIwEENS7_9allocatorIwEEEEwNS0_8identityEEENS7_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SF_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSH_EEEENS1_16projected_helperISP_SK_vEEEEPKT0_EENSJ_IX14borrowed_rangeISH_EEE4typeISP_NS0_8danglingEEEE4typeEOSH_RSU_SK_EUlRKSH_E_JRwEEENSG_IXntsr3std17is_member_pointerIu7__decayISH_EEE5valueEDTclclsr3stdE7forwardISH_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeES12_DpOS1B_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRwEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISA_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSA_DpOSC_ _ZN4nano6ranges6detail7invoke_2fn4implIRZNK3scn2v24impl25character_set_reader_implIwE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_JRKNSt3__14pairIDiDiEEEEENSG_9enable_ifIXntsr3std17is_member_pointerIu7__decayISB_EEE5valueEDTclclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSB_DpOSN_ Line | Count | Source | 1288 | 4.77M | { | 1289 | 4.77M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 4.77M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl23read_regex_matches_implIwNSt3__117basic_string_viewIwNS9_11char_traitsIwEEEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSA_IT_NSB_ISK_EEEENS6_6detail11regex_flagsESG_RNS6_19basic_regex_matchesISK_EEEUlOSK_E_JRKNS9_9sub_matchIPKwEEEEENS9_9enable_ifIXntsr3std17is_member_pointerIu7__decayISK_EEE5valueEDTclclsr3stdE7forwardISK_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeESS_DpOS13_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJRKNSt3__19sub_matchIPKwEEEEENS7_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISF_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSF_DpOSH_ Unexecuted instantiation: _ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl23read_regex_matches_implIwNS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSt3__117basic_string_viewIT_NSL_11char_traitsISN_EEEENS6_6detail11regex_flagsESH_RNS6_19basic_regex_matchesISN_EEEUlOSN_E_JRKNSL_9sub_matchISC_EEEEENSL_9enable_ifIXntsr3std17is_member_pointerIu7__decayISN_EEE5valueEDTclclsr3stdE7forwardISN_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeESW_DpOS15_ _ZN4nano6ranges6detail7invoke_2fn4implIRN3scn2v24impl12function_refIFbwES9_EEJwEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISE_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSE_DpOSG_ Line | Count | Source | 1288 | 484k | { | 1289 | 484k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 484k | } |
_ZN4nano6ranges6detail7invoke_2fn4implIRNS0_8identityEJwEEENSt3__19enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardIS9_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOS9_DpOSB_ Line | Count | Source | 1288 | 484k | { | 1289 | 484k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 484k | } |
find_whitespace.cpp:_ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl12_GLOBAL__N_133find_nondecimal_digit_simple_implENSt3__117basic_string_viewIcNS9_11char_traitsIcEEEEE3$_0JRKcEEENS9_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISJ_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSJ_DpOSL_ Line | Count | Source | 1288 | 182k | { | 1289 | 182k | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 182k | } |
find_whitespace.cpp:_ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl30find_classic_space_narrow_fastENSt3__117basic_string_viewIcNS8_11char_traitsIcEEEEE3$_0JRKcEEENS8_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISI_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSI_DpOSK_ Line | Count | Source | 1288 | 40.6M | { | 1289 | 40.6M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 40.6M | } |
find_whitespace.cpp:_ZN4nano6ranges6detail7invoke_2fn4implIRZN3scn2v24impl33find_classic_nonspace_narrow_fastENSt3__117basic_string_viewIcNS8_11char_traitsIcEEEEE3$_0JRKcEEENS8_9enable_ifIXntsr3std17is_member_pointerIu7__decayIT_EEE5valueEDTclclsr3stdE7forwardISI_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEE4typeEOSI_DpOSK_ Line | Count | Source | 1288 | 12.1M | { | 1289 | 12.1M | return std::forward<F>(f)(std::forward<Args>(args)...); | 1290 | 12.1M | } |
|
1291 | | |
1292 | | public: |
1293 | | template <typename F, typename... Args> |
1294 | | constexpr auto operator()(F&& f, Args&&... args) const |
1295 | | noexcept(noexcept(fn::impl(std::forward<F>(f), |
1296 | | std::forward<Args>(args)...))) |
1297 | | -> decltype(fn::impl(std::forward<F>(f), |
1298 | | std::forward<Args>(args)...)) |
1299 | 148M | { |
1300 | 148M | return fn::impl(std::forward<F>(f), |
1301 | 148M | std::forward<Args>(args)...); |
1302 | 148M | } Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKiEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS9_DpOSA_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_4lessEJRKiS8_EEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS9_DpOSA_ _ZNK4nano6ranges6detail7invoke_2fnclIRN3scn2v24impl12function_refIFbcES9_EEJRKcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSE_DpOSF_ Line | Count | Source | 1299 | 7.36M | { | 1300 | 7.36M | return fn::impl(std::forward<F>(f), | 1301 | 7.36M | std::forward<Args>(args)...); | 1302 | 7.36M | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS9_DpOSA_ Line | Count | Source | 1299 | 60.3M | { | 1300 | 60.3M | return fn::impl(std::forward<F>(f), | 1301 | 60.3M | std::forward<Args>(args)...); | 1302 | 60.3M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRKZNKS1_7find_fnclIRNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEcNS0_8identityEEENS7_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SF_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSH_EEEENS1_16projected_helperISP_SK_vEEEEPKT0_EENSJ_IX14borrowed_rangeISH_EEE4typeISP_NS0_8danglingEEEE4typeEOSH_RSU_SK_EUlRKSH_E_JRcEEEDTclsr2fnE4implclsr3stdE7forwardISH_Efp_Espclsr3stdE7forwardIT0_Efp0_EEES12_DpOS1A_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS8_DpOS9_ _ZNK4nano6ranges6detail7invoke_2fnclIRN3scn2v24impl12function_refIFbcES9_EEJcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSC_DpOSD_ Line | Count | Source | 1299 | 271k | { | 1300 | 271k | return fn::impl(std::forward<F>(f), | 1301 | 271k | std::forward<Args>(args)...); | 1302 | 271k | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS7_DpOS8_ Line | Count | Source | 1299 | 271k | { | 1300 | 271k | return fn::impl(std::forward<F>(f), | 1301 | 271k | std::forward<Args>(args)...); | 1302 | 271k | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_4lessEJRNSt3__14pairIDiDiEESA_EEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSB_DpOSC_ Line | Count | Source | 1299 | 915k | { | 1300 | 915k | return fn::impl(std::forward<F>(f), | 1301 | 915k | std::forward<Args>(args)...); | 1302 | 915k | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRNSt3__14pairIDiDiEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSB_DpOSC_ Line | Count | Source | 1299 | 1.83M | { | 1300 | 1.83M | return fn::impl(std::forward<F>(f), | 1301 | 1.83M | std::forward<Args>(args)...); | 1302 | 1.83M | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRZNK3scn2v24impl25character_set_reader_implIcE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_JRKNSt3__14pairIDiDiEEEEEDTclsr2fnE4implclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSB_DpOSL_ Line | Count | Source | 1299 | 999k | { | 1300 | 999k | return fn::impl(std::forward<F>(f), | 1301 | 999k | std::forward<Args>(args)...); | 1302 | 999k | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKNSt3__14pairIDiDiEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSC_DpOSD_ Line | Count | Source | 1299 | 5.77M | { | 1300 | 5.77M | return fn::impl(std::forward<F>(f), | 1301 | 5.77M | std::forward<Args>(args)...); | 1302 | 5.77M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl23read_regex_matches_implIcNSt3__117basic_string_viewIcNS9_11char_traitsIcEEEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSA_IT_NSB_ISK_EEEENS6_6detail11regex_flagsESG_RNS6_19basic_regex_matchesISK_EEEUlOSK_E_JRKNS9_9sub_matchIPKcEEEEEDTclsr2fnE4implclsr3stdE7forwardISK_Efp_Espclsr3stdE7forwardIT0_Efp0_EEESS_DpOS11_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKNSt3__19sub_matchIPKcEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSE_DpOSF_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl23read_regex_matches_implIcNS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSt3__117basic_string_viewIT_NSL_11char_traitsISN_EEEENS6_6detail11regex_flagsESH_RNS6_19basic_regex_matchesISN_EEEUlOSN_E_JRKNSL_9sub_matchISC_EEEEEDTclsr2fnE4implclsr3stdE7forwardISN_Efp_Espclsr3stdE7forwardIT0_Efp0_EEESW_DpOS13_ _ZNK4nano6ranges6detail7invoke_2fnclIRN3scn2v24impl12function_refIFbwES9_EEJRKwEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSE_DpOSF_ Line | Count | Source | 1299 | 5.89M | { | 1300 | 5.89M | return fn::impl(std::forward<F>(f), | 1301 | 5.89M | std::forward<Args>(args)...); | 1302 | 5.89M | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKwEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS9_DpOSA_ Line | Count | Source | 1299 | 5.89M | { | 1300 | 5.89M | return fn::impl(std::forward<F>(f), | 1301 | 5.89M | std::forward<Args>(args)...); | 1302 | 5.89M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRKZNKS1_7find_fnclIRNSt3__112basic_stringIwNS7_11char_traitsIwEENS7_9allocatorIwEEEEwNS0_8identityEEENS7_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SF_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSH_EEEENS1_16projected_helperISP_SK_vEEEEPKT0_EENSJ_IX14borrowed_rangeISH_EEE4typeISP_NS0_8danglingEEEE4typeEOSH_RSU_SK_EUlRKSH_E_JRwEEEDTclsr2fnE4implclsr3stdE7forwardISH_Efp_Espclsr3stdE7forwardIT0_Efp0_EEES12_DpOS1A_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRwEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS8_DpOS9_ _ZNK4nano6ranges6detail7invoke_2fnclIRZNK3scn2v24impl25character_set_reader_implIwE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_JRKNSt3__14pairIDiDiEEEEEDTclsr2fnE4implclsr3stdE7forwardISB_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSB_DpOSL_ Line | Count | Source | 1299 | 4.77M | { | 1300 | 4.77M | return fn::impl(std::forward<F>(f), | 1301 | 4.77M | std::forward<Args>(args)...); | 1302 | 4.77M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl23read_regex_matches_implIwNSt3__117basic_string_viewIwNS9_11char_traitsIwEEEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSA_IT_NSB_ISK_EEEENS6_6detail11regex_flagsESG_RNS6_19basic_regex_matchesISK_EEEUlOSK_E_JRKNS9_9sub_matchIPKwEEEEEDTclsr2fnE4implclsr3stdE7forwardISK_Efp_Espclsr3stdE7forwardIT0_Efp0_EEESS_DpOS11_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJRKNSt3__19sub_matchIPKwEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSE_DpOSF_ Unexecuted instantiation: _ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl23read_regex_matches_implIwNS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEENS6_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSt3__117basic_string_viewIT_NSL_11char_traitsISN_EEEENS6_6detail11regex_flagsESH_RNS6_19basic_regex_matchesISN_EEEUlOSN_E_JRKNSL_9sub_matchISC_EEEEEDTclsr2fnE4implclsr3stdE7forwardISN_Efp_Espclsr3stdE7forwardIT0_Efp0_EEESW_DpOS13_ _ZNK4nano6ranges6detail7invoke_2fnclIRN3scn2v24impl12function_refIFbwES9_EEJwEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSC_DpOSD_ Line | Count | Source | 1299 | 484k | { | 1300 | 484k | return fn::impl(std::forward<F>(f), | 1301 | 484k | std::forward<Args>(args)...); | 1302 | 484k | } |
_ZNK4nano6ranges6detail7invoke_2fnclIRNS0_8identityEJwEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOS7_DpOS8_ Line | Count | Source | 1299 | 484k | { | 1300 | 484k | return fn::impl(std::forward<F>(f), | 1301 | 484k | std::forward<Args>(args)...); | 1302 | 484k | } |
find_whitespace.cpp:_ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl12_GLOBAL__N_133find_nondecimal_digit_simple_implENSt3__117basic_string_viewIcNS9_11char_traitsIcEEEEE3$_0JRKcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSI_DpOSJ_ Line | Count | Source | 1299 | 182k | { | 1300 | 182k | return fn::impl(std::forward<F>(f), | 1301 | 182k | std::forward<Args>(args)...); | 1302 | 182k | } |
find_whitespace.cpp:_ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl30find_classic_space_narrow_fastENSt3__117basic_string_viewIcNS8_11char_traitsIcEEEEE3$_0JRKcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSH_DpOSI_ Line | Count | Source | 1299 | 40.6M | { | 1300 | 40.6M | return fn::impl(std::forward<F>(f), | 1301 | 40.6M | std::forward<Args>(args)...); | 1302 | 40.6M | } |
find_whitespace.cpp:_ZNK4nano6ranges6detail7invoke_2fnclIRZN3scn2v24impl33find_classic_nonspace_narrow_fastENSt3__117basic_string_viewIcNS8_11char_traitsIcEEEEE3$_0JRKcEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Espclsr3stdE7forwardIT0_Efp0_EEEOSH_DpOSI_ Line | Count | Source | 1299 | 12.1M | { | 1300 | 12.1M | return fn::impl(std::forward<F>(f), | 1301 | 12.1M | std::forward<Args>(args)...); | 1302 | 12.1M | } |
|
1303 | | }; |
1304 | | |
1305 | | } // namespace invoke_ |
1306 | | } // namespace detail |
1307 | | |
1308 | | NANO_INLINE_VAR(nano::detail::invoke_::fn, invoke) |
1309 | | |
1310 | | namespace detail { |
1311 | | |
1312 | | template <typename Void, typename, typename...> |
1313 | | struct invoke_result_helper {}; |
1314 | | |
1315 | | template <typename F, typename... Args> |
1316 | | struct invoke_result_helper< |
1317 | | std::void_t<decltype(nano::invoke(std::declval<F>(), |
1318 | | std::declval<Args>()...))>, |
1319 | | F, |
1320 | | Args...> { |
1321 | | using type = |
1322 | | decltype(nano::invoke(std::declval<F>(), std::declval<Args>()...)); |
1323 | | }; |
1324 | | |
1325 | | } // namespace detail |
1326 | | |
1327 | | template <typename F, typename... Args> |
1328 | | struct invoke_result : detail::invoke_result_helper<void, F, Args...> {}; |
1329 | | |
1330 | | template <typename F, typename... Args> |
1331 | | using invoke_result_t = typename invoke_result<F, Args...>::type; |
1332 | | |
1333 | | NANO_END_NAMESPACE |
1334 | | |
1335 | | #endif |
1336 | | |
1337 | | NANO_BEGIN_NAMESPACE |
1338 | | |
1339 | | // [concept.movable] |
1340 | | namespace detail { |
1341 | | |
1342 | | struct movable_concept { |
1343 | | template <typename T> |
1344 | | static auto test(long) -> std::false_type; |
1345 | | |
1346 | | template <typename T> |
1347 | | static auto test(int) |
1348 | | -> std::enable_if_t<std::is_object_v<T> && move_constructible<T> && |
1349 | | assignable_from<T&, T> && swappable<T>, |
1350 | | std::true_type>; |
1351 | | }; |
1352 | | } // namespace detail |
1353 | | |
1354 | | template <typename T> |
1355 | | NANO_CONCEPT movable = decltype(detail::movable_concept::test<T>(0))::value; |
1356 | | |
1357 | | // [concept.copyable] |
1358 | | namespace detail { |
1359 | | |
1360 | | struct copyable_concept { |
1361 | | template <typename> |
1362 | | static auto test(long) -> std::false_type; |
1363 | | |
1364 | | template <typename T> |
1365 | | static auto test(int) -> std::enable_if_t< |
1366 | | copy_constructible<T> && movable<T> && assignable_from<T&, T&> && |
1367 | | assignable_from<T&, const T&> && assignable_from<T&, const T>, |
1368 | | std::true_type>; |
1369 | | }; |
1370 | | |
1371 | | } // namespace detail |
1372 | | |
1373 | | template <typename T> |
1374 | | NANO_CONCEPT copyable = decltype(detail::copyable_concept::test<T>(0))::value; |
1375 | | |
1376 | | // [concept.semiregular] |
1377 | | template <typename T> |
1378 | | NANO_CONCEPT semiregular = copyable<T> && default_initializable<T>; |
1379 | | |
1380 | | // [concept.regular] |
1381 | | template <typename T> |
1382 | | NANO_CONCEPT regular = semiregular<T> && equality_comparable<T>; |
1383 | | |
1384 | | // [concept.invocable] |
1385 | | namespace detail { |
1386 | | |
1387 | | struct invocable_concept { |
1388 | | // FIXME (Clang): https://bugs.llvm.org/show_bug.cgi?id=21446 |
1389 | | #if (defined(__clang_major__) && \ |
1390 | | (defined(__apple_build_version__) || __clang_major__ < 7)) |
1391 | | template <typename F, typename... Args> |
1392 | | auto requires_(F&& f, Args&&... args) -> invoke_result_t<F, Args...>; |
1393 | | #else |
1394 | | template <typename F, typename... Args> |
1395 | | auto requires_(F&& f, Args&&... args) |
1396 | | -> decltype(nano::invoke(std::forward<F>(f), |
1397 | | std::forward<Args>(args)...)); |
1398 | | #endif |
1399 | | }; |
1400 | | |
1401 | | } // namespace detail |
1402 | | |
1403 | | template <typename F, typename... Args> |
1404 | | NANO_CONCEPT invocable = |
1405 | | detail::requires_<detail::invocable_concept, F, Args...>; |
1406 | | |
1407 | | // [concept.regularinvocable] |
1408 | | template <typename F, typename... Args> |
1409 | | NANO_CONCEPT regular_invocable = invocable<F, Args...>; |
1410 | | |
1411 | | // [concept.predicate] |
1412 | | namespace detail { |
1413 | | |
1414 | | struct predicate_concept { |
1415 | | template <typename, typename...> |
1416 | | static auto test(long) -> std::false_type; |
1417 | | |
1418 | | template <typename F, typename... Args> |
1419 | | static auto test(int) -> std::enable_if_t< |
1420 | | regular_invocable<F, Args...> && |
1421 | | boolean_testable<invoke_result_t<F, Args...>>, |
1422 | | std::true_type>; |
1423 | | }; |
1424 | | |
1425 | | } // namespace detail |
1426 | | |
1427 | | template <typename F, typename... Args> |
1428 | | NANO_CONCEPT predicate = |
1429 | | decltype(detail::predicate_concept::test<F, Args...>(0))::value; |
1430 | | |
1431 | | // [concept.relation] |
1432 | | template <typename R, typename T, typename U> |
1433 | | NANO_CONCEPT relation = predicate<R, T, T> && predicate<R, U, U> && |
1434 | | predicate<R, T, U> && predicate<R, U, T>; |
1435 | | |
1436 | | // [concept.equiv] |
1437 | | template <typename R, typename T, typename U> |
1438 | | NANO_CONCEPT equivalence_relation = relation<R, T, U>; |
1439 | | |
1440 | | // [concept.strictweakorder] |
1441 | | template <typename R, typename T, typename U> |
1442 | | NANO_CONCEPT strict_weak_order = relation<R, T, U>; |
1443 | | |
1444 | | NANO_END_NAMESPACE |
1445 | | |
1446 | | #endif |
1447 | | |
1448 | | // nanorange/detail/iterator/associated_types.hpp |
1449 | | // |
1450 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1451 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1452 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1453 | | |
1454 | | #ifndef NANORANGE_DETAIL_ITERATOR_ASSOCIATED_TYPES_HPP_INCLUDED |
1455 | | #define NANORANGE_DETAIL_ITERATOR_ASSOCIATED_TYPES_HPP_INCLUDED |
1456 | | |
1457 | | NANO_BEGIN_NAMESPACE |
1458 | | |
1459 | | template <typename> |
1460 | | struct incrementable_traits; |
1461 | | |
1462 | | namespace detail { |
1463 | | |
1464 | | struct empty {}; |
1465 | | |
1466 | | template <typename T> |
1467 | | struct with_difference_type { |
1468 | | using difference_type = T; |
1469 | | }; |
1470 | | |
1471 | | template <typename, typename = void> |
1472 | | struct incrementable_traits_helper {}; |
1473 | | |
1474 | | // Workaround for GCC silliness: void* has no difference_type |
1475 | | // FIXME: This is required to stop WeaklyIncrementable<void*> being a hard |
1476 | | // error Can we formulate the concept differently to avoid the need for this |
1477 | | // hack? |
1478 | | template <> |
1479 | | struct incrementable_traits_helper<void*> {}; |
1480 | | |
1481 | | template <typename T> |
1482 | | struct incrementable_traits_helper<T*> |
1483 | | : detail::conditional_t<std::is_object<T>::value, |
1484 | | with_difference_type<std::ptrdiff_t>, |
1485 | | empty> {}; |
1486 | | |
1487 | | template <class I> |
1488 | | struct incrementable_traits_helper<const I> |
1489 | | : incrementable_traits<std::decay_t<I>> {}; |
1490 | | |
1491 | | template <typename, typename = void> |
1492 | | struct has_member_difference_type : std::false_type {}; |
1493 | | |
1494 | | template <typename T> |
1495 | | struct has_member_difference_type<T, |
1496 | | std::void_t<typename T::difference_type>> |
1497 | | : std::true_type {}; |
1498 | | |
1499 | | template <typename T> |
1500 | | constexpr bool has_member_difference_type_v = |
1501 | | has_member_difference_type<T>::value; |
1502 | | |
1503 | | template <typename T> |
1504 | | struct incrementable_traits_helper< |
1505 | | T, |
1506 | | std::enable_if_t<has_member_difference_type_v<T>>> { |
1507 | | using difference_type = typename T::difference_type; |
1508 | | }; |
1509 | | |
1510 | | template <typename T> |
1511 | | struct incrementable_traits_helper< |
1512 | | T, |
1513 | | std::enable_if_t<!std::is_pointer<T>::value && |
1514 | | !has_member_difference_type_v<T> && |
1515 | | integral<decltype(std::declval<const T&>() - |
1516 | | std::declval<const T&>())>>> |
1517 | | : with_difference_type<std::make_signed_t< |
1518 | | decltype(std::declval<T>() - std::declval<T>())>> {}; |
1519 | | |
1520 | | } // namespace detail |
1521 | | |
1522 | | template <typename T> |
1523 | | struct incrementable_traits : detail::incrementable_traits_helper<T> {}; |
1524 | | |
1525 | | template <typename T> |
1526 | | using iter_difference_t = typename incrementable_traits<T>::difference_type; |
1527 | | |
1528 | | // [range.iterator.assoc.types.value_type] |
1529 | | |
1530 | | template <typename> |
1531 | | struct readable_traits; |
1532 | | |
1533 | | namespace detail { |
1534 | | |
1535 | | template <typename T> |
1536 | | struct with_value_type { |
1537 | | using value_type = T; |
1538 | | }; |
1539 | | |
1540 | | template <typename, typename = void> |
1541 | | struct readable_traits_helper {}; |
1542 | | |
1543 | | template <typename T> |
1544 | | struct readable_traits_helper<T*> |
1545 | | : detail::conditional_t<std::is_object<T>::value, |
1546 | | with_value_type<std::remove_cv_t<T>>, |
1547 | | empty> {}; |
1548 | | |
1549 | | template <typename I> |
1550 | | struct readable_traits_helper<I, std::enable_if_t<std::is_array<I>::value>> |
1551 | | : readable_traits<std::decay_t<I>> {}; |
1552 | | |
1553 | | template <typename I> |
1554 | | struct readable_traits_helper<const I, |
1555 | | std::enable_if_t<!std::is_array<I>::value>> |
1556 | | : readable_traits<std::decay_t<I>> {}; |
1557 | | |
1558 | | template <typename T, typename V = typename T::value_type> |
1559 | | struct member_value_type : detail::conditional_t<std::is_object<V>::value, |
1560 | | with_value_type<V>, |
1561 | | empty> {}; |
1562 | | |
1563 | | template <typename T, typename E = typename T::element_type> |
1564 | | struct member_element_type |
1565 | | : detail::conditional_t<std::is_object<E>::value, |
1566 | | with_value_type<std::remove_cv_t<E>>, |
1567 | | empty> {}; |
1568 | | |
1569 | | template <typename T> |
1570 | | using member_value_type_t = typename T::value_type; |
1571 | | |
1572 | | template <typename T> |
1573 | | constexpr bool has_member_value_type_v = exists_v<member_value_type_t, T>; |
1574 | | |
1575 | | template <typename T> |
1576 | | using member_element_type_t = typename T::element_type; |
1577 | | |
1578 | | template <typename T> |
1579 | | constexpr bool has_member_element_type_v = |
1580 | | exists_v<member_element_type_t, T>; |
1581 | | |
1582 | | template <typename T> |
1583 | | struct readable_traits_helper< |
1584 | | T, |
1585 | | std::enable_if_t<has_member_value_type_v<T> && |
1586 | | !has_member_element_type_v<T>>> |
1587 | | : member_value_type<T> {}; |
1588 | | |
1589 | | template <typename T> |
1590 | | struct readable_traits_helper< |
1591 | | T, |
1592 | | std::enable_if_t<has_member_element_type_v<T> && |
1593 | | !has_member_value_type_v<T>>> |
1594 | | : member_element_type<T> {}; |
1595 | | |
1596 | | // A type which has both value_type and element_type members must specialise |
1597 | | // readable_traits to tell us which one to prefer -- see |
1598 | | // https://github.com/ericniebler/stl2/issues/562 |
1599 | | template <typename T> |
1600 | | struct readable_traits_helper< |
1601 | | T, |
1602 | | std::enable_if_t<has_member_element_type_v<T> && |
1603 | | has_member_value_type_v<T>>> {}; |
1604 | | |
1605 | | } // namespace detail |
1606 | | |
1607 | | template <typename T> |
1608 | | struct readable_traits : detail::readable_traits_helper<T> {}; |
1609 | | |
1610 | | template <typename T> |
1611 | | using iter_value_t = typename readable_traits<T>::value_type; |
1612 | | |
1613 | | NANO_END_NAMESPACE |
1614 | | |
1615 | | #endif |
1616 | | |
1617 | | // nanorange/detail/iterator/traits.hpp |
1618 | | // |
1619 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1620 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1621 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1622 | | |
1623 | | #ifndef NANORANGE_DETAIL_ITERATOR_TRAITS_HPP_INCLUDED |
1624 | | #define NANORANGE_DETAIL_ITERATOR_TRAITS_HPP_INCLUDED |
1625 | | |
1626 | | // nanorange/detail/iterator/dereferenceable.hpp |
1627 | | // |
1628 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1629 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1630 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1631 | | |
1632 | | #ifndef NANORANGE_DETAIL_ITERATOR_DEREFERENCABLE_HPP_INCLUDED |
1633 | | #define NANORANGE_DETAIL_ITERATOR_DEREFERENCABLE_HPP_INCLUDED |
1634 | | |
1635 | | NANO_BEGIN_NAMESPACE |
1636 | | |
1637 | | namespace detail { |
1638 | | |
1639 | | template <typename T> |
1640 | | using with_reference = T&; |
1641 | | |
1642 | | struct can_reference_concept { |
1643 | | template <typename T> |
1644 | | auto requires_() -> with_reference<T>; |
1645 | | }; |
1646 | | |
1647 | | template <typename T> |
1648 | | NANO_CONCEPT can_reference = detail::requires_<can_reference_concept, T>; |
1649 | | |
1650 | | struct dereferencable_concept { |
1651 | | template <typename T> |
1652 | | auto requires_(T& t) |
1653 | | -> decltype(requires_expr<can_reference<decltype(*t)>>{}); |
1654 | | }; |
1655 | | |
1656 | | template <typename T> |
1657 | | NANO_CONCEPT dereferenceable = requires_<dereferencable_concept, T>; |
1658 | | |
1659 | | // GCC and Clang allow dereferencing void* as an extension. |
1660 | | // Let's kill that off now. |
1661 | | |
1662 | | template <> |
1663 | | NANO_CONCEPT dereferenceable<void*> = false; |
1664 | | |
1665 | | } // namespace detail |
1666 | | |
1667 | | NANO_END_NAMESPACE |
1668 | | |
1669 | | #endif |
1670 | | |
1671 | | // nanorange/detail/iterator/iter_move.hpp |
1672 | | // |
1673 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
1674 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
1675 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1676 | | |
1677 | | #ifndef NANORANGE_DETAIL_ITERATOR_ITER_MOVE_HPP_INCLUDED |
1678 | | #define NANORANGE_DETAIL_ITERATOR_ITER_MOVE_HPP_INCLUDED |
1679 | | |
1680 | | #include <utility> |
1681 | | |
1682 | | NANO_BEGIN_NAMESPACE |
1683 | | |
1684 | | namespace detail { |
1685 | | namespace iter_move_ { |
1686 | | |
1687 | | void iter_move(); |
1688 | | |
1689 | | struct fn { |
1690 | | private: |
1691 | | template <typename T> |
1692 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
1693 | | noexcept(iter_move(t))) -> decltype(iter_move(t)) |
1694 | | { |
1695 | | return iter_move(t); |
1696 | | } |
1697 | | |
1698 | | template <typename T> |
1699 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
1700 | | noexcept(std::move(*std::declval<T&&>()))) |
1701 | | -> std::enable_if_t<std::is_lvalue_reference< |
1702 | | decltype(*std::forward<T>(t))>::value, |
1703 | | decltype(std::move(*std::forward<T>(t)))> |
1704 | 108k | { |
1705 | 108k | return std::move(*std::forward<T>(t)); |
1706 | 108k | } |
1707 | | |
1708 | | template <typename T> |
1709 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
1710 | | noexcept(*std::forward<T>(t))) -> decltype(*std::forward<T>(t)) |
1711 | | { |
1712 | | return *std::forward<T>(t); |
1713 | | } |
1714 | | |
1715 | | public: |
1716 | | template <typename T> |
1717 | | constexpr auto operator()(T&& t) const |
1718 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
1719 | | priority_tag<2>{}))) |
1720 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<2>{})) |
1721 | 108k | { |
1722 | 108k | return fn::impl(std::forward<T>(t), priority_tag<2>{}); |
1723 | 108k | } |
1724 | | }; |
1725 | | |
1726 | | } // namespace iter_move_ |
1727 | | } // namespace detail |
1728 | | |
1729 | | NANO_INLINE_VAR(detail::iter_move_::fn, iter_move) |
1730 | | |
1731 | | NANO_END_NAMESPACE |
1732 | | |
1733 | | #endif |
1734 | | |
1735 | | #include <iterator> |
1736 | | |
1737 | | NANO_BEGIN_NAMESPACE |
1738 | | |
1739 | | // [range.iterator.assoc.types.iterator_category] |
1740 | | using std::bidirectional_iterator_tag; |
1741 | | using std::forward_iterator_tag; |
1742 | | using std::input_iterator_tag; |
1743 | | using std::output_iterator_tag; |
1744 | | using std::random_access_iterator_tag; |
1745 | | |
1746 | | struct contiguous_iterator_tag : random_access_iterator_tag {}; |
1747 | | |
1748 | | template <typename T> |
1749 | | struct iterator_category; |
1750 | | |
1751 | | namespace detail { |
1752 | | |
1753 | | template <typename T, typename = void> |
1754 | | struct iterator_category_ {}; |
1755 | | |
1756 | | template <typename T> |
1757 | | struct iterator_category_<T*> |
1758 | | : std::enable_if<std::is_object<T>::value, contiguous_iterator_tag> {}; |
1759 | | |
1760 | | template <typename T> |
1761 | | struct iterator_category_<const T> : iterator_category<T> {}; |
1762 | | |
1763 | | template <typename T> |
1764 | | struct iterator_category_<T, std::void_t<typename T::iterator_category>> { |
1765 | | using type = typename T::iterator_category; |
1766 | | }; |
1767 | | |
1768 | | } // namespace detail |
1769 | | |
1770 | | template <typename T> |
1771 | | struct iterator_category : detail::iterator_category_<T> {}; |
1772 | | |
1773 | | template <typename T> |
1774 | | using iterator_category_t = typename iterator_category<T>::type; |
1775 | | |
1776 | | namespace detail { |
1777 | | |
1778 | | template <typename T, typename = void> |
1779 | | struct legacy_iterator_category : iterator_category<T> {}; |
1780 | | |
1781 | | template <typename T> |
1782 | | struct legacy_iterator_category< |
1783 | | T, |
1784 | | std::enable_if_t<std::is_same<iterator_category_t<T>, |
1785 | | contiguous_iterator_tag>::value>> { |
1786 | | using type = random_access_iterator_tag; |
1787 | | }; |
1788 | | |
1789 | | template <typename T> |
1790 | | using legacy_iterator_category_t = |
1791 | | typename legacy_iterator_category<T>::type; |
1792 | | |
1793 | | } // namespace detail |
1794 | | |
1795 | | template <typename T> |
1796 | | using iter_reference_t = |
1797 | | std::enable_if_t<detail::dereferenceable<T>, decltype(*std::declval<T&>())>; |
1798 | | |
1799 | | namespace detail { |
1800 | | |
1801 | | struct iter_rvalue_reference_req { |
1802 | | template <typename T> |
1803 | | auto requires_(T& t) |
1804 | | -> decltype(ranges::iter_move(t), |
1805 | | requires_expr< |
1806 | | can_reference<decltype(ranges::iter_move(t))>>{}); |
1807 | | }; |
1808 | | |
1809 | | } // namespace detail |
1810 | | |
1811 | | template <typename T> |
1812 | | using iter_rvalue_reference_t = std::enable_if_t< |
1813 | | detail::dereferenceable<T> && |
1814 | | detail::requires_<detail::iter_rvalue_reference_req, T>, |
1815 | | decltype(ranges::iter_move(std::declval<T&>()))>; |
1816 | | |
1817 | | NANO_END_NAMESPACE |
1818 | | |
1819 | | #endif |
1820 | | |
1821 | | NANO_BEGIN_NAMESPACE |
1822 | | |
1823 | | // [iterators.concept.readable] |
1824 | | namespace detail { |
1825 | | |
1826 | | struct readable_concept { |
1827 | | template <typename In> |
1828 | | auto requires_() |
1829 | | -> decltype(std::declval<iter_value_t<In>>(), |
1830 | | std::declval<iter_reference_t<In>>(), |
1831 | | std::declval<iter_rvalue_reference_t<In>>()); |
1832 | | |
1833 | | template <typename> |
1834 | | static auto test(long) -> std::false_type; |
1835 | | |
1836 | | template <typename In> |
1837 | | static auto test(int) -> std::enable_if_t< |
1838 | | detail::requires_<readable_concept, In> && |
1839 | | common_reference_with<iter_reference_t<In>&&, |
1840 | | iter_value_t<In>&> && |
1841 | | common_reference_with<iter_reference_t<In>&&, |
1842 | | iter_rvalue_reference_t<In>&&> && |
1843 | | common_reference_with<iter_rvalue_reference_t<In>&&, |
1844 | | const iter_value_t<In>&>, |
1845 | | std::true_type>; |
1846 | | }; |
1847 | | |
1848 | | } // namespace detail |
1849 | | |
1850 | | template <typename In> |
1851 | | NANO_CONCEPT readable = decltype(detail::readable_concept::test<In>(0))::value; |
1852 | | |
1853 | | // [iterator.concept.writable] |
1854 | | namespace detail { |
1855 | | |
1856 | | struct writable_concept { |
1857 | | template <typename Out, typename T> |
1858 | | auto requires_(Out&& o, T&& t) |
1859 | | -> decltype(*o = std::forward<T>(t), |
1860 | | *std::forward<Out>(o) = std::forward<T>(t), |
1861 | | const_cast<const iter_reference_t<Out>&&>(*o) = |
1862 | | std::forward<T>(t), |
1863 | | const_cast<const iter_reference_t<Out>&&>( |
1864 | | *std::forward<Out>(o)) = std::forward<T>(t)); |
1865 | | }; |
1866 | | |
1867 | | } // namespace detail |
1868 | | |
1869 | | template <typename Out, typename T> |
1870 | | NANO_CONCEPT writable = detail::requires_<detail::writable_concept, Out, T>; |
1871 | | |
1872 | | // [iterator.concept.weaklyincrementable] |
1873 | | |
1874 | | namespace detail { |
1875 | | |
1876 | | template <typename T> |
1877 | | inline constexpr bool is_integer_like = integral<T>; |
1878 | | |
1879 | | template <typename T> |
1880 | | inline constexpr bool is_signed_integer_like = signed_integral<T>; |
1881 | | |
1882 | | struct weakly_incrementable_concept { |
1883 | | template <typename I> |
1884 | | auto requires_(I i) |
1885 | | -> decltype(std::declval<iter_difference_t<I>>(), |
1886 | | requires_expr< |
1887 | | is_signed_integer_like<iter_difference_t<I>>>{}, |
1888 | | requires_expr<same_as<decltype(++i), I&>>{}, |
1889 | | i++); |
1890 | | }; |
1891 | | |
1892 | | } // namespace detail |
1893 | | |
1894 | | template <typename I> |
1895 | | NANO_CONCEPT weakly_incrementable = |
1896 | | default_initializable<I> && movable<I> && |
1897 | | detail::requires_<detail::weakly_incrementable_concept, I>; |
1898 | | |
1899 | | // [iterator.concept.incrementable] |
1900 | | namespace detail { |
1901 | | |
1902 | | struct incrementable_concept { |
1903 | | template <typename I> |
1904 | | auto requires_(I i) |
1905 | | -> decltype(requires_expr<same_as<decltype(i++), I>>{}); |
1906 | | }; |
1907 | | |
1908 | | } // namespace detail |
1909 | | |
1910 | | template <typename I> |
1911 | | NANO_CONCEPT incrementable = |
1912 | | regular<I> && weakly_incrementable<I> && |
1913 | | detail::requires_<detail::incrementable_concept, I>; |
1914 | | |
1915 | | // [iterator.concept.iterator] |
1916 | | |
1917 | | namespace detail { |
1918 | | |
1919 | | struct input_or_output_iterator_concept { |
1920 | | template <typename I> |
1921 | | auto requires_(I i) |
1922 | | -> decltype(requires_expr<can_reference<decltype(*i)>>{}); |
1923 | | }; |
1924 | | |
1925 | | } // namespace detail |
1926 | | |
1927 | | template <typename I> |
1928 | | NANO_CONCEPT input_or_output_iterator = |
1929 | | detail::requires_<detail::input_or_output_iterator_concept, I> && |
1930 | | weakly_incrementable<I>; |
1931 | | |
1932 | | // [iterator.concept.sentinel] |
1933 | | |
1934 | | template <typename S, typename I> |
1935 | | NANO_CONCEPT sentinel_for = semiregular<S> && input_or_output_iterator<I> && |
1936 | | detail::weakly_equality_comparable_with<S, I>; |
1937 | | |
1938 | | // [iterator.concept.sizedsentinel] |
1939 | | |
1940 | | template <typename S, typename I> |
1941 | | inline constexpr bool disable_sized_sentinel = false; |
1942 | | |
1943 | | namespace detail { |
1944 | | |
1945 | | struct sized_sentinel_for_concept { |
1946 | | template <typename S, typename I> |
1947 | | auto requires_(const S& s, const I& i) |
1948 | | -> decltype(requires_expr< |
1949 | | same_as<decltype(s - i), iter_difference_t<I>>>{}, |
1950 | | requires_expr< |
1951 | | same_as<decltype(i - s), iter_difference_t<I>>>{}); |
1952 | | }; |
1953 | | |
1954 | | } // namespace detail |
1955 | | |
1956 | | template <typename S, typename I> |
1957 | | NANO_CONCEPT sized_sentinel_for = |
1958 | | sentinel_for<S, I> && |
1959 | | !disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>> && |
1960 | | detail::requires_<detail::sized_sentinel_for_concept, S, I>; |
1961 | | |
1962 | | // This is a hack, but I'm fed up with my tests breaking because GCC |
1963 | | // has a silly extension |
1964 | | template <typename S> |
1965 | | NANO_CONCEPT sized_sentinel_for<S, void*> = false; |
1966 | | |
1967 | | template <typename I> |
1968 | | NANO_CONCEPT sized_sentinel_for<void*, I> = false; |
1969 | | |
1970 | | template <> |
1971 | | NANO_CONCEPT sized_sentinel_for<void*, void*> = false; |
1972 | | |
1973 | | // [iterator.concept.input] |
1974 | | |
1975 | | namespace detail { |
1976 | | |
1977 | | // FIXME: Use ITER_CONCEPT, not iterator_category_t |
1978 | | struct input_iterator_concept { |
1979 | | template <typename I> |
1980 | | auto requires_() -> iterator_category_t<I>; |
1981 | | |
1982 | | template <typename> |
1983 | | static auto test(long) -> std::false_type; |
1984 | | |
1985 | | template <typename I> |
1986 | | static auto test(int) -> std::enable_if_t< |
1987 | | input_or_output_iterator<I> && readable<I> && |
1988 | | detail::requires_<input_iterator_concept, I> && |
1989 | | derived_from<iterator_category_t<I>, input_iterator_tag>, |
1990 | | std::true_type>; |
1991 | | }; |
1992 | | |
1993 | | } // namespace detail |
1994 | | |
1995 | | template <typename I> |
1996 | | NANO_CONCEPT input_iterator = |
1997 | | decltype(detail::input_iterator_concept::test<I>(0))::value; |
1998 | | |
1999 | | // [iterator.concept.output] |
2000 | | |
2001 | | namespace detail { |
2002 | | |
2003 | | struct output_iterator_concept { |
2004 | | template <typename I, typename T> |
2005 | | auto requires_(I i, T&& t) -> decltype(*i++ = std::forward<T>(t)); |
2006 | | }; |
2007 | | |
2008 | | } // namespace detail |
2009 | | |
2010 | | template <typename I, typename T> |
2011 | | NANO_CONCEPT output_iterator = |
2012 | | input_or_output_iterator<I> && writable<I, T> && |
2013 | | detail::requires_<detail::output_iterator_concept, I, T>; |
2014 | | |
2015 | | // [ranges.iterators.forward] |
2016 | | |
2017 | | namespace detail { |
2018 | | |
2019 | | struct forward_iterator_concept { |
2020 | | template <typename> |
2021 | | static auto test(long) -> std::false_type; |
2022 | | |
2023 | | template <typename I> |
2024 | | static auto test(int) -> std::enable_if_t< |
2025 | | input_iterator<I> && |
2026 | | derived_from<iterator_category_t<I>, forward_iterator_tag> && |
2027 | | incrementable<I> && sentinel_for<I, I>, |
2028 | | std::true_type>; |
2029 | | }; |
2030 | | |
2031 | | } // namespace detail |
2032 | | |
2033 | | template <typename I> |
2034 | | NANO_CONCEPT forward_iterator = |
2035 | | decltype(detail::forward_iterator_concept::test<I>(0))::value; |
2036 | | |
2037 | | // [iterator.concept.bidir] |
2038 | | namespace detail { |
2039 | | |
2040 | | struct bidirectional_iterator_concept { |
2041 | | template <typename I> |
2042 | | auto requires_(I i) |
2043 | | -> decltype(requires_expr<same_as<decltype(--i), I&>>{}, |
2044 | | requires_expr<same_as<decltype(i--), I>>{}); |
2045 | | |
2046 | | template <typename> |
2047 | | static auto test(long) -> std::false_type; |
2048 | | |
2049 | | template <typename I> |
2050 | | static auto test(int) -> std::enable_if_t< |
2051 | | forward_iterator<I> && |
2052 | | derived_from<iterator_category_t<I>, |
2053 | | bidirectional_iterator_tag> && |
2054 | | detail::requires_<bidirectional_iterator_concept, I>, |
2055 | | std::true_type>; |
2056 | | }; |
2057 | | |
2058 | | } // namespace detail |
2059 | | |
2060 | | template <typename I> |
2061 | | NANO_CONCEPT bidirectional_iterator = |
2062 | | decltype(detail::bidirectional_iterator_concept::test<I>(0))::value; |
2063 | | |
2064 | | // [iterator.concept.random.access] |
2065 | | |
2066 | | namespace detail { |
2067 | | |
2068 | | struct random_access_iterator_concept { |
2069 | | template <typename> |
2070 | | static auto test(long) -> std::false_type; |
2071 | | |
2072 | | template <typename I> |
2073 | | static auto test(int) -> std::enable_if_t< |
2074 | | bidirectional_iterator<I> && |
2075 | | derived_from<iterator_category_t<I>, |
2076 | | random_access_iterator_tag> && |
2077 | | totally_ordered<I> && sized_sentinel_for<I, I> && |
2078 | | detail::requires_<random_access_iterator_concept, I>, |
2079 | | std::true_type>; |
2080 | | |
2081 | | template <typename I> |
2082 | | auto requires_(I i, const I j, const iter_difference_t<I> n) |
2083 | | -> decltype(requires_expr<same_as<decltype(i += n), I&>>{}, |
2084 | | requires_expr<same_as<decltype(j + n), I>>{}, |
2085 | | #ifndef _MSC_VER |
2086 | | requires_expr<same_as<decltype(n + j), |
2087 | | I>>{}, // FIXME: MSVC doesn't |
2088 | | // like this when I = int* |
2089 | | #endif |
2090 | | requires_expr<same_as<decltype(i -= n), I&>>{}, |
2091 | | requires_expr<same_as<decltype(j - n), I>>{}, |
2092 | | requires_expr< |
2093 | | same_as<decltype(j[n]), iter_reference_t<I>>>{}); |
2094 | | }; |
2095 | | |
2096 | | } // namespace detail |
2097 | | |
2098 | | template <typename I> |
2099 | | NANO_CONCEPT random_access_iterator = |
2100 | | decltype(detail::random_access_iterator_concept::test<I>(0))::value; |
2101 | | |
2102 | | namespace detail { |
2103 | | |
2104 | | struct contiguous_iterator_concept { |
2105 | | template <typename> |
2106 | | static auto test(long) -> std::false_type; |
2107 | | |
2108 | | template <typename I> |
2109 | | static auto test(int) -> std::enable_if_t< |
2110 | | random_access_iterator<I> && |
2111 | | derived_from<iterator_category_t<I>, contiguous_iterator_tag> && |
2112 | | std::is_lvalue_reference_v<iter_reference_t<I>> && |
2113 | | same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>>, |
2114 | | std::true_type>; |
2115 | | }; |
2116 | | |
2117 | | } // namespace detail |
2118 | | |
2119 | | template <typename I> |
2120 | | NANO_CONCEPT contiguous_iterator = |
2121 | | decltype(detail::contiguous_iterator_concept::test<I>(0))::value; |
2122 | | |
2123 | | NANO_END_NAMESPACE |
2124 | | |
2125 | | #endif |
2126 | | |
2127 | | NANO_BEGIN_NAMESPACE |
2128 | | |
2129 | | template <typename T> |
2130 | | using iter_common_reference_t = |
2131 | | std::enable_if_t<readable<T>, |
2132 | | common_reference_t<iter_reference_t<T>, iter_value_t<T>&>>; |
2133 | | |
2134 | | // [iterator.concept.indirectinvocable] |
2135 | | namespace detail { |
2136 | | |
2137 | | struct indirect_unary_invocable_concept { |
2138 | | template <typename, typename> |
2139 | | static auto test(long) -> std::false_type; |
2140 | | |
2141 | | template <typename F, typename I> |
2142 | | static auto test(int) -> std::enable_if_t< |
2143 | | readable<I> && copy_constructible<F> && |
2144 | | invocable<F&, iter_value_t<I>&> && |
2145 | | invocable<F&, iter_reference_t<I>> && |
2146 | | invocable<F&, iter_common_reference_t<I>> && |
2147 | | common_reference_with< |
2148 | | invoke_result_t<F&, iter_value_t<I>&>, |
2149 | | invoke_result_t<F&, iter_reference_t<I>&>>, |
2150 | | std::true_type>; |
2151 | | }; |
2152 | | |
2153 | | } // namespace detail |
2154 | | |
2155 | | template <typename F, typename I> |
2156 | | NANO_CONCEPT indirect_unary_invocable = |
2157 | | decltype(detail::indirect_unary_invocable_concept::test<F, I>(0))::value; |
2158 | | |
2159 | | namespace detail { |
2160 | | |
2161 | | struct indirect_regular_unary_invocable_concept { |
2162 | | template <typename, typename> |
2163 | | static auto test(long) -> std::false_type; |
2164 | | |
2165 | | template <typename F, typename I> |
2166 | | static auto test(int) -> std::enable_if_t< |
2167 | | readable<I> && copy_constructible<F> && |
2168 | | regular_invocable<F&, iter_value_t<I>&> && |
2169 | | regular_invocable<F&, iter_reference_t<I>> && |
2170 | | regular_invocable<F&, iter_common_reference_t<I>> && |
2171 | | common_reference_with< |
2172 | | invoke_result_t<F&, iter_value_t<I>&>, |
2173 | | invoke_result_t<F&, iter_reference_t<I>&>>, |
2174 | | std::true_type>; |
2175 | | }; |
2176 | | |
2177 | | } // namespace detail |
2178 | | |
2179 | | template <typename F, typename I> |
2180 | | NANO_CONCEPT indirect_regular_unary_invocable = |
2181 | | decltype(detail::indirect_regular_unary_invocable_concept::test<F, I>( |
2182 | | 0))::value; |
2183 | | |
2184 | | namespace detail { |
2185 | | |
2186 | | struct indirect_unary_predicate_concept { |
2187 | | template <typename, typename> |
2188 | | static auto test(long) -> std::false_type; |
2189 | | |
2190 | | template <typename F, typename I> |
2191 | | static auto test(int) |
2192 | | -> std::enable_if_t<readable<I> && copy_constructible<F> && |
2193 | | predicate<F&, iter_value_t<I>&> && |
2194 | | predicate<F&, iter_reference_t<I>> && |
2195 | | predicate<F&, iter_common_reference_t<I>>, |
2196 | | std::true_type>; |
2197 | | }; |
2198 | | |
2199 | | } // namespace detail |
2200 | | |
2201 | | template <typename F, typename I> |
2202 | | NANO_CONCEPT indirect_unary_predicate = |
2203 | | decltype(detail::indirect_unary_predicate_concept::test<F, I>(0))::value; |
2204 | | |
2205 | | namespace detail { |
2206 | | |
2207 | | struct indirect_relation_concept { |
2208 | | template <typename F, typename I1, typename I2> |
2209 | | static auto test(long) -> std::false_type; |
2210 | | |
2211 | | template <typename F, typename I1, typename I2> |
2212 | | static auto test(int) -> std::enable_if_t< |
2213 | | readable<I1> && readable<I2> && copy_constructible<F> && |
2214 | | relation<F&, iter_value_t<I1>&, iter_value_t<I2>&> && |
2215 | | relation<F&, iter_value_t<I1>&, iter_reference_t<I2>> && |
2216 | | relation<F&, iter_reference_t<I1>, iter_value_t<I2>&> && |
2217 | | relation<F&, iter_reference_t<I1>, iter_reference_t<I2>> && |
2218 | | relation<F&, |
2219 | | iter_common_reference_t<I1>, |
2220 | | iter_common_reference_t<I2>>, |
2221 | | std::true_type>; |
2222 | | }; |
2223 | | |
2224 | | } // namespace detail |
2225 | | |
2226 | | template <typename F, typename I1, typename I2 = I1> |
2227 | | NANO_CONCEPT indirect_relation = |
2228 | | decltype(detail::indirect_relation_concept::test<F, I1, I2>(0))::value; |
2229 | | |
2230 | | namespace detail { |
2231 | | |
2232 | | struct indirect_strict_weak_order_concept { |
2233 | | template <typename, typename, typename> |
2234 | | static auto test(long) -> std::false_type; |
2235 | | |
2236 | | template <typename F, typename I1, typename I2> |
2237 | | static auto test(int) -> std::enable_if_t< |
2238 | | readable<I1> && readable<I2> && copy_constructible<F> && |
2239 | | strict_weak_order<F&, iter_value_t<I1>&, iter_value_t<I2>&> && |
2240 | | strict_weak_order<F&, |
2241 | | iter_value_t<I1>&, |
2242 | | iter_reference_t<I2>> && |
2243 | | strict_weak_order<F&, |
2244 | | iter_reference_t<I1>, |
2245 | | iter_value_t<I2>&> && |
2246 | | strict_weak_order<F&, |
2247 | | iter_reference_t<I1>, |
2248 | | iter_reference_t<I2>> && |
2249 | | strict_weak_order<F&, |
2250 | | iter_common_reference_t<I1>, |
2251 | | iter_common_reference_t<I2>>, |
2252 | | std::true_type>; |
2253 | | }; |
2254 | | |
2255 | | } // namespace detail |
2256 | | |
2257 | | template <typename F, typename I1, typename I2 = I1> |
2258 | | NANO_CONCEPT indirect_strict_weak_order = |
2259 | | decltype(detail::indirect_strict_weak_order_concept::test<F, I1, I2>( |
2260 | | 0))::value; |
2261 | | |
2262 | | template <typename F, typename... Is> |
2263 | | using indirect_result_t = |
2264 | | std::enable_if_t<(readable<Is> && ...) && |
2265 | | invocable<F, iter_reference_t<Is>...>, |
2266 | | invoke_result_t<F, iter_reference_t<Is>...>>; |
2267 | | |
2268 | | // [alg.req.ind.move] |
2269 | | |
2270 | | namespace detail { |
2271 | | |
2272 | | struct indirectly_movable_concept { |
2273 | | template <typename, typename> |
2274 | | static auto test(long) -> std::false_type; |
2275 | | |
2276 | | template <typename In, typename Out> |
2277 | | static auto test(int) |
2278 | | -> std::enable_if_t<readable<In> && |
2279 | | writable<Out, iter_rvalue_reference_t<In>>, |
2280 | | std::true_type>; |
2281 | | }; |
2282 | | |
2283 | | } // namespace detail |
2284 | | |
2285 | | template <typename In, typename Out> |
2286 | | NANO_CONCEPT indirectly_movable = |
2287 | | decltype(detail::indirectly_movable_concept::test<In, Out>(0))::value; |
2288 | | |
2289 | | namespace detail { |
2290 | | |
2291 | | struct indirectly_movable_storable_concept { |
2292 | | template <typename In, typename Out> |
2293 | | static auto test(long) -> std::false_type; |
2294 | | |
2295 | | template <typename In, typename Out> |
2296 | | static auto test(int) -> std::enable_if_t< |
2297 | | indirectly_movable<In, Out> && writable<Out, iter_value_t<In>> && |
2298 | | movable<iter_value_t<In>> && |
2299 | | constructible_from<iter_value_t<In>, |
2300 | | iter_rvalue_reference_t<In>> && |
2301 | | assignable_from<iter_value_t<In>&, iter_rvalue_reference_t<In>>, |
2302 | | std::true_type>; |
2303 | | }; |
2304 | | |
2305 | | } // namespace detail |
2306 | | |
2307 | | template <typename In, typename Out> |
2308 | | NANO_CONCEPT indirectly_movable_storable = |
2309 | | decltype(detail::indirectly_movable_storable_concept::test<In, Out>( |
2310 | | 0))::value; |
2311 | | |
2312 | | // [alg.req.ind.copy] |
2313 | | namespace detail { |
2314 | | |
2315 | | struct indirectly_copyable_concept { |
2316 | | template <typename, typename> |
2317 | | static auto test(long) -> std::false_type; |
2318 | | |
2319 | | template <typename In, typename Out> |
2320 | | static auto test(int) |
2321 | | -> std::enable_if_t<readable<In> && |
2322 | | writable<Out, iter_reference_t<In>>, |
2323 | | std::true_type>; |
2324 | | }; |
2325 | | |
2326 | | } // namespace detail |
2327 | | |
2328 | | template <typename In, typename Out> |
2329 | | NANO_CONCEPT indirectly_copyable = |
2330 | | decltype(detail::indirectly_copyable_concept::test<In, Out>(0))::value; |
2331 | | |
2332 | | namespace detail { |
2333 | | |
2334 | | struct indirectly_copyable_storable_concept { |
2335 | | template <typename, typename> |
2336 | | static auto test(long) -> std::false_type; |
2337 | | |
2338 | | template <typename In, typename Out> |
2339 | | static auto test(int) -> std::enable_if_t< |
2340 | | indirectly_copyable<In, Out> && |
2341 | | writable<Out, const iter_value_t<In>&> && |
2342 | | copyable<iter_value_t<In>> && |
2343 | | constructible_from<iter_value_t<In>, iter_reference_t<In>> && |
2344 | | assignable_from<iter_value_t<In>&, iter_reference_t<In>>, |
2345 | | std::true_type>; |
2346 | | }; |
2347 | | |
2348 | | } // namespace detail |
2349 | | |
2350 | | template <typename In, typename Out> |
2351 | | NANO_CONCEPT indirectly_copyable_storable = |
2352 | | decltype(detail::indirectly_copyable_storable_concept::test<In, Out>( |
2353 | | 0))::value; |
2354 | | |
2355 | | NANO_END_NAMESPACE |
2356 | | |
2357 | | #endif |
2358 | | |
2359 | | // nanorange/detail/iterator/iter_swap.hpp |
2360 | | // |
2361 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2362 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2363 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2364 | | |
2365 | | #ifndef NANORANGE_DETAIL_ITERATOR_ITER_SWAP_HPP_INCLUDED |
2366 | | #define NANORANGE_DETAIL_ITERATOR_ITER_SWAP_HPP_INCLUDED |
2367 | | |
2368 | | NANO_BEGIN_NAMESPACE |
2369 | | |
2370 | | namespace detail { |
2371 | | namespace iter_swap_ { |
2372 | | |
2373 | | // ADL "poison pill" |
2374 | | template <typename I1, typename I2> |
2375 | | void iter_swap(I1, I2) = delete; |
2376 | | |
2377 | | // FIXME MSVC: add a second (redundant) poison pill |
2378 | | template <typename I> |
2379 | | void iter_swap(I, I) = delete; |
2380 | | |
2381 | | struct fn { |
2382 | | private: |
2383 | | template <typename X, typename Y> |
2384 | | static constexpr iter_value_t<std::remove_reference_t<X>> |
2385 | | iter_exchange_move(X&& x, Y&& y) noexcept(noexcept( |
2386 | | iter_value_t<std::remove_reference_t<X>>(ranges::iter_move( |
2387 | | x))) && noexcept(*x = ranges::iter_move(y))) |
2388 | | { |
2389 | | iter_value_t<std::remove_reference_t<X>> old_value( |
2390 | | ranges::iter_move(x)); |
2391 | | *x = ranges::iter_move(y); |
2392 | | return old_value; |
2393 | | } |
2394 | | |
2395 | | template <typename T, typename U> |
2396 | | static constexpr auto impl(T&& t, U&& u, priority_tag<2>) noexcept( |
2397 | | noexcept((void)(iter_swap(std::forward<T>(t), |
2398 | | std::forward<U>(u))))) |
2399 | | -> decltype((void)(iter_swap(std::forward<T>(t), |
2400 | | std::forward<U>(u)))) |
2401 | | { |
2402 | | (void)iter_swap(std::forward<T>(t), std::forward<U>(u)); |
2403 | | } |
2404 | | |
2405 | | template <typename T, typename U> |
2406 | | static constexpr auto impl(T&& t, U&& u, priority_tag<1>) noexcept( |
2407 | | noexcept(ranges::swap(*std::forward<T>(t), |
2408 | | *std::forward<U>(u)))) |
2409 | | -> std::enable_if_t< |
2410 | | readable<std::remove_reference_t<T>> && |
2411 | | readable<std::remove_reference_t<U>> && |
2412 | | swappable_with<iter_reference_t<T>, iter_reference_t<U>>> |
2413 | 83.5k | { |
2414 | 83.5k | ranges::swap(*std::forward<T>(t), *std::forward<U>(u)); |
2415 | 83.5k | } _ZN4nano6ranges6detail10iter_swap_2fn4implIRNSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESB_EENS5_9enable_ifIXaaaa8readableIu20__remove_reference_tIT_EE8readableIu20__remove_reference_tIT0_EE14swappable_withINSC_IXsr6detailE15dereferenceableISD_EEDTdeclsr3stdE7declvalIRSD_EEEE4typeENSC_IXsr6detailE15dereferenceableISF_EEDTdeclsr3stdE7declvalIRSF_EEEE4typeEEEvE4typeEOSD_OSF_NS1_12priority_tagILm1EEE Line | Count | Source | 2413 | 66.3k | { | 2414 | 66.3k | ranges::swap(*std::forward<T>(t), *std::forward<U>(u)); | 2415 | 66.3k | } |
_ZN4nano6ranges6detail10iter_swap_2fn4implIRNSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESA_EENS5_9enable_ifIXaaaa8readableIu20__remove_reference_tIT_EE8readableIu20__remove_reference_tIT0_EE14swappable_withINSC_IXsr6detailE15dereferenceableISD_EEDTdeclsr3stdE7declvalIRSD_EEEE4typeENSC_IXsr6detailE15dereferenceableISF_EEDTdeclsr3stdE7declvalIRSF_EEEE4typeEEEvE4typeEOSD_OSF_NS1_12priority_tagILm1EEE Line | Count | Source | 2413 | 6.87k | { | 2414 | 6.87k | ranges::swap(*std::forward<T>(t), *std::forward<U>(u)); | 2415 | 6.87k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10iter_swap_2fn4implINSt3__111__wrap_iterIPNS5_4pairIDiDiEEEERSA_EENS5_9enable_ifIXaaaa8readableIu20__remove_reference_tIT_EE8readableIu20__remove_reference_tIT0_EE14swappable_withINSC_IXsr6detailE15dereferenceableISD_EEDTdeclsr3stdE7declvalIRSD_EEEE4typeENSC_IXsr6detailE15dereferenceableISF_EEDTdeclsr3stdE7declvalIRSF_EEEE4typeEEEvE4typeEOSD_OSF_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail10iter_swap_2fn4implINSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESA_EENS5_9enable_ifIXaaaa8readableIu20__remove_reference_tIT_EE8readableIu20__remove_reference_tIT0_EE14swappable_withINSB_IXsr6detailE15dereferenceableISC_EEDTdeclsr3stdE7declvalIRSC_EEEE4typeENSB_IXsr6detailE15dereferenceableISE_EEDTdeclsr3stdE7declvalIRSE_EEEE4typeEEEvE4typeEOSC_OSE_NS1_12priority_tagILm1EEE Line | Count | Source | 2413 | 10.3k | { | 2414 | 10.3k | ranges::swap(*std::forward<T>(t), *std::forward<U>(u)); | 2415 | 10.3k | } |
|
2416 | | |
2417 | | template <typename T, typename U> |
2418 | | static constexpr auto impl(T&& t, U&& u, priority_tag<0>) noexcept( |
2419 | | noexcept(*t = fn::iter_exchange_move(std::forward<U>(u), |
2420 | | std::forward<T>(t)))) |
2421 | | -> std::enable_if_t<indirectly_movable_storable<T, U> && |
2422 | | indirectly_movable_storable<U, T>> |
2423 | | { |
2424 | | return *t = fn::iter_exchange_move(std::forward<U>(u), |
2425 | | std::forward<T>(t)); |
2426 | | } |
2427 | | |
2428 | | public: |
2429 | | template <typename T, typename U> |
2430 | | constexpr auto operator()(T&& t, U&& u) const |
2431 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
2432 | | std::forward<U>(u), |
2433 | | priority_tag<2>{}))) |
2434 | | -> decltype(fn::impl(std::forward<T>(t), |
2435 | | std::forward<U>(u), |
2436 | | priority_tag<2>{})) |
2437 | 83.5k | { |
2438 | 83.5k | return fn::impl(std::forward<T>(t), std::forward<U>(u), |
2439 | 83.5k | priority_tag<2>{}); |
2440 | 83.5k | } _ZNK4nano6ranges6detail10iter_swap_2fnclIRNSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESB_EEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Eclsr3stdE7forwardIT0_Efp0_EtlNS1_12priority_tagILm2EEEEEEOSC_OSD_ Line | Count | Source | 2437 | 66.3k | { | 2438 | 66.3k | return fn::impl(std::forward<T>(t), std::forward<U>(u), | 2439 | 66.3k | priority_tag<2>{}); | 2440 | 66.3k | } |
_ZNK4nano6ranges6detail10iter_swap_2fnclIRNSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESA_EEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Eclsr3stdE7forwardIT0_Efp0_EtlNS1_12priority_tagILm2EEEEEEOSC_OSD_ Line | Count | Source | 2437 | 6.87k | { | 2438 | 6.87k | return fn::impl(std::forward<T>(t), std::forward<U>(u), | 2439 | 6.87k | priority_tag<2>{}); | 2440 | 6.87k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail10iter_swap_2fnclINSt3__111__wrap_iterIPNS5_4pairIDiDiEEEERSA_EEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Eclsr3stdE7forwardIT0_Efp0_EtlNS1_12priority_tagILm2EEEEEEOSC_OSD_ _ZNK4nano6ranges6detail10iter_swap_2fnclINSt3__111__wrap_iterIPNS5_4pairIDiDiEEEESA_EEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_Eclsr3stdE7forwardIT0_Efp0_EtlNS1_12priority_tagILm2EEEEEEOSB_OSC_ Line | Count | Source | 2437 | 10.3k | { | 2438 | 10.3k | return fn::impl(std::forward<T>(t), std::forward<U>(u), | 2439 | 10.3k | priority_tag<2>{}); | 2440 | 10.3k | } |
|
2441 | | }; |
2442 | | } // namespace iter_swap_ |
2443 | | } // namespace detail |
2444 | | |
2445 | | NANO_INLINE_VAR(detail::iter_swap_::fn, iter_swap) |
2446 | | |
2447 | | NANO_END_NAMESPACE |
2448 | | |
2449 | | #endif |
2450 | | |
2451 | | // nanorange/detail/iterator/projected.hpp |
2452 | | // |
2453 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2454 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2455 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2456 | | |
2457 | | #ifndef NANORANGE_DETAIL_ITERATOR_PROJECTED_HPP_INCLUDED |
2458 | | #define NANORANGE_DETAIL_ITERATOR_PROJECTED_HPP_INCLUDED |
2459 | | |
2460 | | NANO_BEGIN_NAMESPACE |
2461 | | |
2462 | | // [range.projected] |
2463 | | |
2464 | | // template <typename I, typename Proj> |
2465 | | // struct projected; |
2466 | | |
2467 | | namespace detail { |
2468 | | |
2469 | | template <typename, typename, typename = void> |
2470 | | struct projected_helper {}; |
2471 | | |
2472 | | template <typename I, typename Proj> |
2473 | | struct projected_helper< |
2474 | | I, |
2475 | | Proj, |
2476 | | std::enable_if_t<readable<I> && |
2477 | | indirect_regular_unary_invocable<Proj, I>>> { |
2478 | | using value_type = remove_cvref_t<indirect_result_t<Proj&, I>>; |
2479 | | |
2480 | | indirect_result_t<Proj&, I> operator*() const; |
2481 | | }; |
2482 | | |
2483 | | template <typename, typename, typename = void> |
2484 | | struct projected_difference_t_helper {}; |
2485 | | |
2486 | | template <typename I, typename Proj> |
2487 | | struct projected_difference_t_helper< |
2488 | | I, |
2489 | | Proj, |
2490 | | std::enable_if_t<weakly_incrementable<I>>> { |
2491 | | using difference_type = iter_difference_t<I>; |
2492 | | }; |
2493 | | |
2494 | | } // namespace detail |
2495 | | |
2496 | | template <typename I, typename Proj> |
2497 | | using projected = detail::conditional_t<same_as<Proj, identity>, |
2498 | | I, |
2499 | | detail::projected_helper<I, Proj>>; |
2500 | | |
2501 | | template <typename I, typename Proj> |
2502 | | struct incrementable_traits<detail::projected_helper<I, Proj>> |
2503 | | : detail::projected_difference_t_helper<I, Proj> {}; |
2504 | | |
2505 | | NANO_END_NAMESPACE |
2506 | | |
2507 | | #endif |
2508 | | |
2509 | | NANO_BEGIN_NAMESPACE |
2510 | | |
2511 | | namespace detail { |
2512 | | |
2513 | | struct indirectly_swappable_concept { |
2514 | | template <typename I1, typename I2> |
2515 | | auto requires_(I1& i1, I2& i2) -> decltype(ranges::iter_swap(i1, i1), |
2516 | | ranges::iter_swap(i2, i2), |
2517 | | ranges::iter_swap(i1, i2), |
2518 | | ranges::iter_swap(i2, i1)); |
2519 | | }; |
2520 | | |
2521 | | } // namespace detail |
2522 | | |
2523 | | template <typename I1, typename I2 = I1> |
2524 | | NANO_CONCEPT indirectly_swappable = |
2525 | | readable<I1> && readable<I2> && |
2526 | | detail::requires_<detail::indirectly_swappable_concept, I1, I2>; |
2527 | | |
2528 | | // [alg.req.ind.cmp] |
2529 | | |
2530 | | template <typename I1, |
2531 | | typename I2, |
2532 | | typename R, |
2533 | | typename P1 = identity, |
2534 | | typename P2 = identity> |
2535 | | NANO_CONCEPT indirectly_comparable = |
2536 | | indirect_relation<R, projected<I1, P1>, projected<I2, P2>>; |
2537 | | |
2538 | | // [alg.req.permutable] |
2539 | | |
2540 | | template <typename I> |
2541 | | NANO_CONCEPT permutable = |
2542 | | forward_iterator<I> && indirectly_movable_storable<I, I> && |
2543 | | indirectly_swappable<I, I>; |
2544 | | |
2545 | | // [alg.req.mergeable] |
2546 | | |
2547 | | template <typename I1, |
2548 | | typename I2, |
2549 | | typename Out, |
2550 | | typename R = ranges::less, |
2551 | | typename P1 = identity, |
2552 | | typename P2 = identity> |
2553 | | NANO_CONCEPT mergeable = |
2554 | | input_iterator<I1> && input_iterator<I2> && weakly_incrementable<Out> && |
2555 | | indirectly_copyable<I1, Out> && indirectly_copyable<I2, Out> && |
2556 | | indirect_strict_weak_order<R, projected<I1, P1>, projected<I2, P2>>; |
2557 | | |
2558 | | // [alg.req.sortable] |
2559 | | |
2560 | | template <typename I, typename R = ranges::less, typename P = identity> |
2561 | | NANO_CONCEPT sortable = |
2562 | | permutable<I> && indirect_strict_weak_order<R, projected<I, P>>; |
2563 | | |
2564 | | NANO_END_NAMESPACE |
2565 | | |
2566 | | #endif |
2567 | | |
2568 | | // nanorange/detail/ranges/access.hpp |
2569 | | // |
2570 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2571 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2572 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2573 | | |
2574 | | #ifndef NANORANGE_DETAIL_RANGES_ACCESS_HPP_INCLUDED |
2575 | | #define NANORANGE_DETAIL_RANGES_ACCESS_HPP_INCLUDED |
2576 | | |
2577 | | // nanorange/detail/ranges/begin_end.hpp |
2578 | | // |
2579 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2580 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2581 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2582 | | |
2583 | | #ifndef NANORANGE_DETAIL_RANGES_BEGIN_END_HPP_INCLUDED |
2584 | | #define NANORANGE_DETAIL_RANGES_BEGIN_END_HPP_INCLUDED |
2585 | | |
2586 | | // nanorange/detail/functional/decay_copy.hpp |
2587 | | // |
2588 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2589 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2590 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2591 | | |
2592 | | #ifndef NANORANGE_DETAIL_FUNCTIONAL_DECAY_COPY_HPP_INCLUDED |
2593 | | #define NANORANGE_DETAIL_FUNCTIONAL_DECAY_COPY_HPP_INCLUDED |
2594 | | |
2595 | | #include <type_traits> |
2596 | | #include <utility> |
2597 | | |
2598 | | NANO_BEGIN_NAMESPACE |
2599 | | |
2600 | | namespace detail { |
2601 | | |
2602 | | template <typename T> |
2603 | | constexpr std::decay_t<T> decay_copy(T&& t) noexcept( |
2604 | | noexcept(static_cast<std::decay_t<T>>(std::forward<T>(t)))) |
2605 | 824M | { |
2606 | 824M | return std::forward<T>(t); |
2607 | 824M | } _ZN4nano6ranges6detail10decay_copyIPKcEEu7__decayIT_EOS5_ Line | Count | Source | 2605 | 210M | { | 2606 | 210M | return std::forward<T>(t); | 2607 | 210M | } |
_ZN4nano6ranges6detail10decay_copyIPKwEEu7__decayIT_EOS5_ Line | Count | Source | 2605 | 314M | { | 2606 | 314M | return std::forward<T>(t); | 2607 | 314M | } |
_ZN4nano6ranges6detail10decay_copyIlEEu7__decayIT_EOS3_ Line | Count | Source | 2605 | 51.0M | { | 2606 | 51.0M | return std::forward<T>(t); | 2607 | 51.0M | } |
_ZN4nano6ranges6detail10decay_copyImEEu7__decayIT_EOS3_ Line | Count | Source | 2605 | 19.6M | { | 2606 | 19.6M | return std::forward<T>(t); | 2607 | 19.6M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPcEEEEu7__decayIT_EOS7_ _ZN4nano6ranges6detail10decay_copyIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorEEEu7__decayIT_EOS9_ Line | Count | Source | 2605 | 7.45M | { | 2606 | 7.45M | return std::forward<T>(t); | 2607 | 7.45M | } |
_ZN4nano6ranges6detail10decay_copyINS0_18default_sentinel_tEEEu7__decayIT_EOS4_ Line | Count | Source | 2605 | 9.99M | { | 2606 | 9.99M | return std::forward<T>(t); | 2607 | 9.99M | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcS9_EEEEu7__decayIT_EOSB_ Line | Count | Source | 2605 | 289k | { | 2606 | 289k | return std::forward<T>(t); | 2607 | 289k | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSA_LNS0_13subrange_kindE1EEEE8sentinelILb1EEEEEu7__decayIT_EOSG_ Line | Count | Source | 2605 | 232k | { | 2606 | 232k | return std::forward<T>(t); | 2607 | 232k | } |
_ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPNS3_4pairIDiDiEEEEEEu7__decayIT_EOS9_ Line | Count | Source | 2605 | 20.9k | { | 2606 | 20.9k | return std::forward<T>(t); | 2607 | 20.9k | } |
_ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPKNS3_4pairIDiDiEEEEEEu7__decayIT_EOSA_ Line | Count | Source | 2605 | 225k | { | 2606 | 225k | return std::forward<T>(t); | 2607 | 225k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPKNS3_9sub_matchIPKcEEEEEEu7__decayIT_EOSC_ _ZN4nano6ranges6detail10decay_copyIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS4_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEEEEu7__decayIT_EOSE_ Line | Count | Source | 2605 | 5.63k | { | 2606 | 5.63k | return std::forward<T>(t); | 2607 | 5.63k | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS4_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEE8sentinelILb1EEEEEu7__decayIT_EOSJ_ Line | Count | Source | 2605 | 1.40k | { | 2606 | 1.40k | return std::forward<T>(t); | 2607 | 1.40k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPwEEEEu7__decayIT_EOS7_ _ZN4nano6ranges6detail10decay_copyIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwS9_EEEEu7__decayIT_EOSB_ Line | Count | Source | 2605 | 188k | { | 2606 | 188k | return std::forward<T>(t); | 2607 | 188k | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSA_LNS0_13subrange_kindE1EEEE8sentinelILb1EEEEEu7__decayIT_EOSG_ Line | Count | Source | 2605 | 97.8k | { | 2606 | 97.8k | return std::forward<T>(t); | 2607 | 97.8k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10decay_copyINSt3__111__wrap_iterIPKNS3_9sub_matchIPKwEEEEEEu7__decayIT_EOSC_ _ZN4nano6ranges6detail10decay_copyIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorEEEu7__decayIT_EOS9_ Line | Count | Source | 2605 | 15.1M | { | 2606 | 15.1M | return std::forward<T>(t); | 2607 | 15.1M | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS4_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEEEEu7__decayIT_EOSE_ Line | Count | Source | 2605 | 18.5k | { | 2606 | 18.5k | return std::forward<T>(t); | 2607 | 18.5k | } |
_ZN4nano6ranges6detail10decay_copyIN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS4_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEE8sentinelILb1EEEEEu7__decayIT_EOSJ_ Line | Count | Source | 2605 | 4.62k | { | 2606 | 4.62k | return std::forward<T>(t); | 2607 | 4.62k | } |
_ZN4nano6ranges6detail10decay_copyINSt3__116__deque_iteratorIcPKcRS5_PKS6_lLl4096EEEEEu7__decayIT_EOSB_ Line | Count | Source | 2605 | 73.6M | { | 2606 | 73.6M | return std::forward<T>(t); | 2607 | 73.6M | } |
_ZN4nano6ranges6detail10decay_copyINSt3__116__deque_iteratorIwPKwRS5_PKS6_lLl1024EEEEEu7__decayIT_EOSB_ Line | Count | Source | 2605 | 121M | { | 2606 | 121M | return std::forward<T>(t); | 2607 | 121M | } |
|
2608 | | |
2609 | | } // namespace detail |
2610 | | |
2611 | | NANO_END_NAMESPACE |
2612 | | |
2613 | | #endif |
2614 | | |
2615 | | // nanorange/detail/ranges/borrowed_range.hpp |
2616 | | // |
2617 | | // Copyright (c) 2020 Tristan Brindle (tcbrindle at gmail dot com) |
2618 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2619 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2620 | | |
2621 | | #ifndef NANORANGE_DETAIL_RANGES_BORROWED_RANGE_HPP_INCLUDED |
2622 | | #define NANORANGE_DETAIL_RANGES_BORROWED_RANGE_HPP_INCLUDED |
2623 | | |
2624 | | NANO_BEGIN_NAMESPACE |
2625 | | |
2626 | | template <typename> |
2627 | | inline constexpr bool enable_borrowed_range = false; |
2628 | | |
2629 | | NANO_END_NAMESPACE |
2630 | | |
2631 | | #endif |
2632 | | |
2633 | | NANO_BEGIN_NAMESPACE |
2634 | | |
2635 | | // [range.access.begin] |
2636 | | |
2637 | | namespace detail { |
2638 | | namespace begin_ { |
2639 | | |
2640 | | template <typename T> |
2641 | | void begin(T&) = delete; |
2642 | | |
2643 | | template <typename T> |
2644 | | void begin(const T&) = delete; |
2645 | | |
2646 | | struct fn { |
2647 | | private: |
2648 | | template <typename T, |
2649 | | std::enable_if_t< |
2650 | | !std::is_lvalue_reference_v<T> && |
2651 | | !enable_borrowed_range<std::remove_cv_t<T>>, |
2652 | | int> = 0> |
2653 | | static constexpr void impl(T&&, priority_tag<3>) = delete; |
2654 | | |
2655 | | template < |
2656 | | typename T, |
2657 | | std::enable_if_t<std::is_array_v<remove_cvref_t<T>>, int> = 0> |
2658 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept |
2659 | | -> decltype(t + 0) |
2660 | | { |
2661 | | return t + 0; |
2662 | | } |
2663 | | |
2664 | | template <typename T> |
2665 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
2666 | | noexcept(decay_copy(std::forward<T>(t).begin()))) |
2667 | | -> std::enable_if_t< |
2668 | | input_or_output_iterator< |
2669 | | decltype(decay_copy(std::forward<T>(t).begin()))>, |
2670 | | decltype(decay_copy(std::forward<T>(t).begin()))> |
2671 | 272M | { |
2672 | 272M | return decay_copy(t.begin()); |
2673 | 272M | } _ZN4nano6ranges6detail6begin_2fn4implIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESD_E4typeEOSC_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 13.6M | { | 2672 | 13.6M | return decay_copy(t.begin()); | 2673 | 13.6M | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESD_E4typeEOSC_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 2.27M | { | 2672 | 2.27M | return decay_copy(t.begin()); | 2673 | 2.27M | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESG_E4typeEOSF_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 45.5M | { | 2672 | 45.5M | return decay_copy(t.begin()); | 2673 | 45.5M | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESG_E4typeEOSF_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 40.0M | { | 2672 | 40.0M | return decay_copy(t.begin()); | 2673 | 40.0M | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESF_E4typeEOSE_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 71.5M | { | 2672 | 71.5M | return decay_copy(t.begin()); | 2673 | 71.5M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESF_E4typeEOSE_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 3.72M | { | 2672 | 3.72M | return decay_copy(t.begin()); | 2673 | 3.72M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 3.73M | { | 2672 | 3.73M | return decay_copy(t.begin()); | 2673 | 3.73M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESJ_E4typeEOSI_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implINS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 2.74k | { | 2672 | 2.74k | return decay_copy(t.begin()); | 2673 | 2.74k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESR_E4typeEOSQ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 588 | { | 2672 | 588 | return decay_copy(t.begin()); | 2673 | 588 | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESQ_E4typeEOSP_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 130k | { | 2672 | 130k | return decay_copy(t.begin()); | 2673 | 130k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 52.5k | { | 2672 | 52.5k | return decay_copy(t.begin()); | 2673 | 52.5k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EESE_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 51.6k | { | 2672 | 51.6k | return decay_copy(t.begin()); | 2673 | 51.6k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESF_E4typeEOSE_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 13.9k | { | 2672 | 13.9k | return decay_copy(t.begin()); | 2673 | 13.9k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESG_E4typeEOSF_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 112k | { | 2672 | 112k | return decay_copy(t.begin()); | 2673 | 112k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNSt3__113match_resultsIPKcNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESH_E4typeEOSG_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESO_E4typeEOSN_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESU_E4typeEOST_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEEST_E4typeEOSS_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESN_E4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 2.81k | { | 2672 | 2.81k | return decay_copy(t.begin()); | 2673 | 2.81k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESO_E4typeEOSN_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 1.40k | { | 2672 | 1.40k | return decay_copy(t.begin()); | 2673 | 1.40k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESF_E4typeEOSE_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 73.9M | { | 2672 | 73.9M | return decay_copy(t.begin()); | 2673 | 73.9M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESF_E4typeEOSE_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implINS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 2.16k | { | 2672 | 2.16k | return decay_copy(t.begin()); | 2673 | 2.16k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESR_E4typeEOSQ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 484 | { | 2672 | 484 | return decay_copy(t.begin()); | 2673 | 484 | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESQ_E4typeEOSP_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 72.5k | { | 2672 | 72.5k | return decay_copy(t.begin()); | 2673 | 72.5k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 49.3k | { | 2672 | 49.3k | return decay_copy(t.begin()); | 2673 | 49.3k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EESE_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 31.9k | { | 2672 | 31.9k | return decay_copy(t.begin()); | 2673 | 31.9k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNSt3__113match_resultsIPKwNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESH_E4typeEOSG_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 7.33M | { | 2672 | 7.33M | return decay_copy(t.begin()); | 2673 | 7.33M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 7.80M | { | 2672 | 7.80M | return decay_copy(t.begin()); | 2673 | 7.80M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESJ_E4typeEOSI_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESO_E4typeEOSN_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESU_E4typeEOST_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEEST_E4typeEOSS_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail6begin_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESN_E4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 9.25k | { | 2672 | 9.25k | return decay_copy(t.begin()); | 2673 | 9.25k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEENSt3__19enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESO_E4typeEOSN_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 4.62k | { | 2672 | 4.62k | return decay_copy(t.begin()); | 2673 | 4.62k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNSt3__15dequeIcNS5_9allocatorIcEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 379k | { | 2672 | 379k | return decay_copy(t.begin()); | 2673 | 379k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEENS7_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 381k | { | 2672 | 381k | return decay_copy(t.begin()); | 2673 | 381k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEENS7_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 1.41k | { | 2672 | 1.41k | return decay_copy(t.begin()); | 2673 | 1.41k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNSt3__15dequeIwNS5_9allocatorIwEEEEEENS5_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESE_E4typeEOSD_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 669k | { | 2672 | 669k | return decay_copy(t.begin()); | 2673 | 669k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEENS7_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESK_E4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 736k | { | 2672 | 736k | return decay_copy(t.begin()); | 2673 | 736k | } |
_ZN4nano6ranges6detail6begin_2fn4implIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEENS7_9enable_ifIX24input_or_output_iteratorIDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E5beginEEEEESL_E4typeEOSK_NS1_12priority_tagILm1EEE Line | Count | Source | 2671 | 33.5k | { | 2672 | 33.5k | return decay_copy(t.begin()); | 2673 | 33.5k | } |
|
2674 | | |
2675 | | template <typename T> |
2676 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
2677 | | noexcept(decay_copy(begin(std::forward<T>(t))))) |
2678 | | -> std::enable_if_t< |
2679 | | input_or_output_iterator< |
2680 | | decltype(decay_copy(begin(std::forward<T>(t))))>, |
2681 | | decltype(decay_copy(begin(std::forward<T>(t))))> |
2682 | | { |
2683 | | return decay_copy(begin(std::forward<T>(t))); |
2684 | | } |
2685 | | |
2686 | | public: |
2687 | | template <typename T> |
2688 | | constexpr auto operator()(T&& t) const |
2689 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
2690 | | priority_tag<3>{}))) |
2691 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<3>{})) |
2692 | 272M | { |
2693 | 272M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); |
2694 | 272M | } _ZNK4nano6ranges6detail6begin_2fnclIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 2692 | 13.6M | { | 2693 | 13.6M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 13.6M | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 2692 | 2.27M | { | 2693 | 2.27M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 2.27M | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2692 | 45.5M | { | 2693 | 45.5M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 45.5M | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2692 | 40.0M | { | 2693 | 40.0M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 40.0M | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2692 | 71.5M | { | 2693 | 71.5M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 71.5M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ _ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 3.72M | { | 2693 | 3.72M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 3.72M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2692 | 3.73M | { | 2693 | 3.73M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 3.73M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSG_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclINS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ _ZNK4nano6ranges6detail6begin_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 2.74k | { | 2693 | 2.74k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 2.74k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSO_ Line | Count | Source | 2692 | 588 | { | 2693 | 588 | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 588 | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSN_ Line | Count | Source | 2692 | 130k | { | 2693 | 130k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 130k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2692 | 52.5k | { | 2693 | 52.5k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 52.5k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EESE_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 51.6k | { | 2693 | 51.6k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 51.6k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2692 | 13.9k | { | 2693 | 13.9k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 13.9k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSE_ Line | Count | Source | 2692 | 112k | { | 2693 | 112k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 112k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNSt3__113match_resultsIPKcNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSF_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSR_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSQ_ _ZNK4nano6ranges6detail6begin_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSK_ Line | Count | Source | 2692 | 2.81k | { | 2693 | 2.81k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 2.81k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Line | Count | Source | 2692 | 1.40k | { | 2693 | 1.40k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 1.40k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2692 | 73.9M | { | 2693 | 73.9M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 73.9M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclINS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ _ZNK4nano6ranges6detail6begin_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 2.16k | { | 2693 | 2.16k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 2.16k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSO_ Line | Count | Source | 2692 | 484 | { | 2693 | 484 | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 484 | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSN_ Line | Count | Source | 2692 | 72.5k | { | 2693 | 72.5k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 72.5k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2692 | 49.3k | { | 2693 | 49.3k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 49.3k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EESE_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 31.9k | { | 2693 | 31.9k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 31.9k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNSt3__113match_resultsIPKwNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSF_ _ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 7.33M | { | 2693 | 7.33M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 7.33M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2692 | 7.80M | { | 2693 | 7.80M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 7.80M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSG_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSR_ Unexecuted instantiation: _ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSQ_ _ZNK4nano6ranges6detail6begin_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSK_ Line | Count | Source | 2692 | 9.25k | { | 2693 | 9.25k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 9.25k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Line | Count | Source | 2692 | 4.62k | { | 2693 | 4.62k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 4.62k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNSt3__15dequeIcNS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2692 | 379k | { | 2693 | 379k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 379k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 381k | { | 2693 | 381k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 381k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSJ_ Line | Count | Source | 2692 | 1.41k | { | 2693 | 1.41k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 1.41k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNSt3__15dequeIwNS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2692 | 669k | { | 2693 | 669k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 669k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2692 | 736k | { | 2693 | 736k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 736k | } |
_ZNK4nano6ranges6detail6begin_2fnclIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSJ_ Line | Count | Source | 2692 | 33.5k | { | 2693 | 33.5k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2694 | 33.5k | } |
|
2695 | | }; |
2696 | | |
2697 | | } // namespace begin_ |
2698 | | } // namespace detail |
2699 | | |
2700 | | NANO_INLINE_VAR(detail::begin_::fn, begin) |
2701 | | |
2702 | | namespace detail { |
2703 | | namespace end_ { |
2704 | | |
2705 | | template <typename T> |
2706 | | void end(T&) = delete; |
2707 | | |
2708 | | template <typename T> |
2709 | | void end(const T&) = delete; |
2710 | | |
2711 | | struct fn { |
2712 | | private: |
2713 | | template <typename T, |
2714 | | std::enable_if_t< |
2715 | | !std::is_lvalue_reference_v<T> && |
2716 | | !enable_borrowed_range<std::remove_cv_t<T>>, |
2717 | | int> = 0> |
2718 | | static constexpr void impl(T&&, priority_tag<3>) = delete; |
2719 | | |
2720 | | template < |
2721 | | typename T, |
2722 | | std::enable_if_t<std::is_array_v<remove_cvref_t<T>>, int> = 0> |
2723 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept |
2724 | | -> decltype(t + std::extent_v<remove_cvref_t<T>>) |
2725 | | { |
2726 | | return t + std::extent_v<remove_cvref_t<T>>; |
2727 | | } |
2728 | | |
2729 | | template < |
2730 | | typename T, |
2731 | | typename S = decltype(decay_copy(std::declval<T>().end())), |
2732 | | typename I = decltype(ranges::begin(std::declval<T>()))> |
2733 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
2734 | | noexcept(decay_copy(std::forward<T>(t).end()))) |
2735 | | -> std::enable_if_t< |
2736 | | sentinel_for<S, I>, |
2737 | | decltype(decay_copy(std::forward<T>(t).end()))> |
2738 | 481M | { |
2739 | 481M | return decay_copy(std::forward<T>(t).end()); |
2740 | 481M | } _ZN4nano6ranges6detail4end_2fn4implIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEPKcSC_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSG_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 18.0M | { | 2739 | 18.0M | return decay_copy(std::forward<T>(t).end()); | 2740 | 18.0M | } |
_ZN4nano6ranges6detail4end_2fn4implIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEPKwSC_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSG_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 8.14M | { | 2739 | 8.14M | return decay_copy(std::forward<T>(t).end()); | 2740 | 8.14M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEES8_S8_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSH_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 34.1M | { | 2739 | 34.1M | return decay_copy(std::forward<T>(t).end()); | 2740 | 34.1M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEES8_S8_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSH_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 113M | { | 2739 | 113M | return decay_copy(std::forward<T>(t).end()); | 2740 | 113M | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEES8_S8_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSG_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 27.2M | { | 2739 | 27.2M | return decay_copy(std::forward<T>(t).end()); | 2740 | 27.2M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS5_11__wrap_iterIPcEESF_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSJ_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEESD_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSL_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 1.55M | { | 2739 | 1.55M | return decay_copy(std::forward<T>(t).end()); | 2740 | 1.55M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEESD_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 1.60M | { | 2739 | 1.60M | return decay_copy(std::forward<T>(t).end()); | 2740 | 1.60M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEPKcSD_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSH_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorESC_LNS0_13subrange_kindE0EEESC_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSK_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEENSF_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISC_SC_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSR_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 2.08k | { | 2739 | 2.08k | return decay_copy(std::forward<T>(t).end()); | 2740 | 2.08k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEESK_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSR_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 166k | { | 2739 | 166k | return decay_copy(std::forward<T>(t).end()); | 2740 | 166k | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEESK_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSS_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 588 | { | 2739 | 588 | return decay_copy(std::forward<T>(t).end()); | 2740 | 588 | } |
_ZN4nano6ranges6detail4end_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEENSF_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISC_SC_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSQ_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 62.8k | { | 2739 | 62.8k | return decay_copy(std::forward<T>(t).end()); | 2740 | 62.8k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EESE_LNS0_13subrange_kindE0EEESE_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 51.6k | { | 2739 | 51.6k | return decay_copy(std::forward<T>(t).end()); | 2740 | 51.6k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEENS5_11__wrap_iterIPS8_EESF_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSJ_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 6.99k | { | 2739 | 6.99k | return decay_copy(std::forward<T>(t).end()); | 2740 | 6.99k | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEENS5_11__wrap_iterIPKS8_EESH_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSL_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 112k | { | 2739 | 112k | return decay_copy(std::forward<T>(t).end()); | 2740 | 112k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNSt3__113match_resultsIPKcNS5_9allocatorINS5_9sub_matchIS8_EEEEEENS5_11__wrap_iterIPKSB_EESI_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSI_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISE_SF_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSU_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEESN_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSU_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEESN_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSV_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSI_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISE_SF_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOST_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 1.40k | { | 2739 | 1.40k | return decay_copy(std::forward<T>(t).end()); | 2740 | 1.40k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEESH_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSP_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 1.40k | { | 2739 | 1.40k | return decay_copy(std::forward<T>(t).end()); | 2740 | 1.40k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEES8_S8_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSG_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 77.1M | { | 2739 | 77.1M | return decay_copy(std::forward<T>(t).end()); | 2740 | 77.1M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEENS5_11__wrap_iterIPwEESF_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSJ_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEENSF_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISC_SC_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSR_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 1.71k | { | 2739 | 1.71k | return decay_copy(std::forward<T>(t).end()); | 2740 | 1.71k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEESK_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSR_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 47.6k | { | 2739 | 47.6k | return decay_copy(std::forward<T>(t).end()); | 2740 | 47.6k | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEESK_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSS_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 484 | { | 2739 | 484 | return decay_copy(std::forward<T>(t).end()); | 2740 | 484 | } |
_ZN4nano6ranges6detail4end_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEENSF_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISC_SC_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSQ_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 48.0k | { | 2739 | 48.0k | return decay_copy(std::forward<T>(t).end()); | 2740 | 48.0k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EESE_LNS0_13subrange_kindE0EEESE_SE_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 31.9k | { | 2739 | 31.9k | return decay_copy(std::forward<T>(t).end()); | 2740 | 31.9k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNSt3__113match_resultsIPKwNS5_9allocatorINS5_9sub_matchIS8_EEEEEENS5_11__wrap_iterIPKSB_EESI_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEESD_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSL_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 3.67M | { | 2739 | 3.67M | return decay_copy(std::forward<T>(t).end()); | 2740 | 3.67M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEESD_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 3.15M | { | 2739 | 3.15M | return decay_copy(std::forward<T>(t).end()); | 2740 | 3.15M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEPKwSD_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSH_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorESC_LNS0_13subrange_kindE0EEESC_SC_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSK_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSI_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISE_SF_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSU_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEESN_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSU_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEESN_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSV_NS1_12priority_tagILm1EEE _ZN4nano6ranges6detail4end_2fn4implIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENSI_8sentinelILb1EEENS7_27counted_width_iterator_impl22counted_width_iteratorISE_SF_EEEENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOST_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 4.62k | { | 2739 | 4.62k | return decay_copy(std::forward<T>(t).end()); | 2740 | 4.62k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEESH_SH_EENSt3__19enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSP_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 4.62k | { | 2739 | 4.62k | return decay_copy(std::forward<T>(t).end()); | 2740 | 4.62k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEESE_SE_EENS7_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSL_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 72.5M | { | 2739 | 72.5M | return decay_copy(std::forward<T>(t).end()); | 2740 | 72.5M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNSt3__15dequeIcNS5_9allocatorIcEEEENS5_16__deque_iteratorIcPKcRSD_PKSE_lLl4096EEESI_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 380k | { | 2739 | 380k | return decay_copy(std::forward<T>(t).end()); | 2740 | 380k | } |
_ZN4nano6ranges6detail4end_2fn4implIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEESE_SE_EENS7_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSL_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 119M | { | 2739 | 119M | return decay_copy(std::forward<T>(t).end()); | 2740 | 119M | } |
_ZN4nano6ranges6detail4end_2fn4implIRKNSt3__15dequeIwNS5_9allocatorIwEEEENS5_16__deque_iteratorIwPKwRSD_PKSE_lLl1024EEESI_EENS5_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Line | Count | Source | 2738 | 703k | { | 2739 | 703k | return decay_copy(std::forward<T>(t).end()); | 2740 | 703k | } |
Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEESE_SE_EENS7_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE Unexecuted instantiation: _ZN4nano6ranges6detail4end_2fn4implIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEESE_SE_EENS7_9enable_ifIX12sentinel_forIT0_T1_EEDTcl10decay_copycldtclsr3stdE7forwardIT_Efp_E3endEEEE4typeEOSM_NS1_12priority_tagILm1EEE |
2741 | | |
2742 | | template <typename T, |
2743 | | typename S = decltype(decay_copy(end(std::declval<T>()))), |
2744 | | typename I = decltype(ranges::begin(std::declval<T>()))> |
2745 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
2746 | | noexcept(decay_copy(end(std::forward<T>(t))))) |
2747 | | -> std::enable_if_t<sentinel_for<S, I>, S> |
2748 | | { |
2749 | | return decay_copy(end(std::forward<T>(t))); |
2750 | | } |
2751 | | |
2752 | | public: |
2753 | | template <typename T> |
2754 | | constexpr auto operator()(T&& t) const |
2755 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
2756 | | priority_tag<3>{}))) |
2757 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<3>{})) |
2758 | 481M | { |
2759 | 481M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); |
2760 | 481M | } _ZNK4nano6ranges6detail4end_2fnclIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 2758 | 18.0M | { | 2759 | 18.0M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 18.0M | } |
_ZNK4nano6ranges6detail4end_2fnclIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 2758 | 8.14M | { | 2759 | 8.14M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 8.14M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2758 | 34.1M | { | 2759 | 34.1M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 34.1M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2758 | 113M | { | 2759 | 113M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 113M | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2758 | 27.2M | { | 2759 | 27.2M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 27.2M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2758 | 1.55M | { | 2759 | 1.55M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 1.55M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 1.60M | { | 2759 | 1.60M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 1.60M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSG_ _ZNK4nano6ranges6detail4end_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 2.08k | { | 2759 | 2.08k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 2.08k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSN_ Line | Count | Source | 2758 | 166k | { | 2759 | 166k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 166k | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSO_ Line | Count | Source | 2758 | 588 | { | 2759 | 588 | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 588 | } |
_ZNK4nano6ranges6detail4end_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2758 | 62.8k | { | 2759 | 62.8k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 62.8k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSD_EESE_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 51.6k | { | 2759 | 51.6k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 51.6k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 2758 | 6.99k | { | 2759 | 6.99k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 6.99k | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNSt3__16vectorINS5_4pairIDiDiEENS5_9allocatorIS8_EEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSE_ Line | Count | Source | 2758 | 112k | { | 2759 | 112k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 112k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNSt3__113match_resultsIPKcNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSF_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSQ_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSR_ _ZNK4nano6ranges6detail4end_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSK_ Line | Count | Source | 2758 | 1.40k | { | 2759 | 1.40k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 1.40k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Line | Count | Source | 2758 | 1.40k | { | 2759 | 1.40k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 1.40k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2758 | 77.1M | { | 2759 | 77.1M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 77.1M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ _ZNK4nano6ranges6detail4end_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 1.71k | { | 2759 | 1.71k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 1.71k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSN_ Line | Count | Source | 2758 | 47.6k | { | 2759 | 47.6k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 47.6k | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EENS9_15take_width_viewINS6_ISD_SD_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSG_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSO_ Line | Count | Source | 2758 | 484 | { | 2759 | 484 | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 484 | } |
_ZNK4nano6ranges6detail4end_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSC_LNS0_13subrange_kindE1EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2758 | 48.0k | { | 2759 | 48.0k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 48.0k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSD_EESE_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 31.9k | { | 2759 | 31.9k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 31.9k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNSt3__113match_resultsIPKwNS5_9allocatorINS5_9sub_matchIS8_EEEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSF_ _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSH_ Line | Count | Source | 2758 | 3.67M | { | 2759 | 3.67M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 3.67M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 3.15M | { | 2759 | 3.15M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 3.15M | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorESC_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSG_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSQ_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS9_15take_width_viewINS6_ISF_SG_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSJ_0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSR_ _ZNK4nano6ranges6detail4end_2fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS6_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSK_ Line | Count | Source | 2758 | 4.62k | { | 2759 | 4.62k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 4.62k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS8_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEESH_LNS0_13subrange_kindE0EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSL_ Line | Count | Source | 2758 | 4.62k | { | 2759 | 4.62k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 4.62k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 72.5M | { | 2759 | 72.5M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 72.5M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNSt3__15dequeIcNS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2758 | 380k | { | 2759 | 380k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 380k | } |
_ZNK4nano6ranges6detail4end_2fnclIRNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSI_ Line | Count | Source | 2758 | 119M | { | 2759 | 119M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 119M | } |
_ZNK4nano6ranges6detail4end_2fnclIRKNSt3__15dequeIwNS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 2758 | 703k | { | 2759 | 703k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 2760 | 703k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIcPKcRS9_PKSA_lLl4096EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSJ_ Unexecuted instantiation: _ZNK4nano6ranges6detail4end_2fnclIRKNS0_9subrange_8subrangeINSt3__116__deque_iteratorIwPKwRS9_PKSA_lLl1024EEESE_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSJ_ |
2761 | | }; |
2762 | | |
2763 | | } // namespace end_ |
2764 | | } // namespace detail |
2765 | | |
2766 | | NANO_INLINE_VAR(detail::end_::fn, end) |
2767 | | |
2768 | | // [range.access.cbegin] |
2769 | | |
2770 | | namespace detail { |
2771 | | namespace cbegin_ { |
2772 | | |
2773 | | struct fn { |
2774 | | private: |
2775 | | template <typename T, |
2776 | | typename U = std::remove_reference_t<T>, |
2777 | | std::enable_if_t<std::is_lvalue_reference_v<T>, int> = 0> |
2778 | | static constexpr auto impl(T&& t) noexcept( |
2779 | | noexcept(ranges::begin(static_cast<const U&>(t)))) |
2780 | | -> decltype(ranges::begin(static_cast<const U&>(t))) |
2781 | | { |
2782 | | return ranges::begin(static_cast<const U&>(t)); |
2783 | | } |
2784 | | |
2785 | | template <typename T, |
2786 | | std::enable_if_t<!std::is_lvalue_reference_v<T>, int> = 0> |
2787 | | static constexpr auto impl(T&& t) noexcept(noexcept( |
2788 | | ranges::begin(static_cast<const T&&>(std::forward<T>(t))))) |
2789 | | -> decltype(ranges::begin( |
2790 | | static_cast<const T&&>(std::forward<T>(t)))) |
2791 | | { |
2792 | | return ranges::begin( |
2793 | | static_cast<const T&&>(std::forward<T>(t))); |
2794 | | } |
2795 | | |
2796 | | public: |
2797 | | template <typename T> |
2798 | | constexpr auto operator()(T&& t) const |
2799 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
2800 | | -> decltype(fn::impl(std::forward<T>(t))) |
2801 | | { |
2802 | | return fn::impl(std::forward<T>(t)); |
2803 | | } |
2804 | | }; |
2805 | | |
2806 | | } // namespace cbegin_ |
2807 | | } // namespace detail |
2808 | | |
2809 | | NANO_INLINE_VAR(detail::cbegin_::fn, cbegin) |
2810 | | |
2811 | | // [ranges.access.cend] |
2812 | | |
2813 | | namespace detail { |
2814 | | namespace cend_ { |
2815 | | |
2816 | | struct fn { |
2817 | | private: |
2818 | | template <typename T, |
2819 | | typename U = std::remove_reference_t<T>, |
2820 | | std::enable_if_t<std::is_lvalue_reference_v<T>, int> = 0> |
2821 | | static constexpr auto impl(T&& t) noexcept( |
2822 | | noexcept(ranges::end(static_cast<const U&>(t)))) |
2823 | | -> decltype(ranges::end(static_cast<const U&>(t))) |
2824 | | { |
2825 | | return ranges::end(static_cast<const U&>(t)); |
2826 | | } |
2827 | | |
2828 | | template <typename T, |
2829 | | std::enable_if_t<!std::is_lvalue_reference_v<T>, int> = 0> |
2830 | | static constexpr auto impl(T&& t) noexcept(noexcept( |
2831 | | ranges::end(static_cast<const T&&>(std::forward<T>(t))))) |
2832 | | -> decltype(ranges::end( |
2833 | | static_cast<const T&&>(std::forward<T>(t)))) |
2834 | | { |
2835 | | return ranges::end(static_cast<const T&&>(std::forward<T>(t))); |
2836 | | } |
2837 | | |
2838 | | public: |
2839 | | template <typename T> |
2840 | | constexpr auto operator()(T&& t) const |
2841 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
2842 | | -> decltype(fn::impl(std::forward<T>(t))) |
2843 | | { |
2844 | | return fn::impl(std::forward<T>(t)); |
2845 | | } |
2846 | | }; |
2847 | | |
2848 | | } // namespace cend_ |
2849 | | } // namespace detail |
2850 | | |
2851 | | NANO_INLINE_VAR(detail::cend_::fn, cend) |
2852 | | |
2853 | | NANO_END_NAMESPACE |
2854 | | |
2855 | | #endif |
2856 | | |
2857 | | // nanorange/iterator/reverse_iterator.hpp |
2858 | | // |
2859 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2860 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2861 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2862 | | |
2863 | | #ifndef NANORANGE_ITERATOR_REVERSE_ITERATOR_HPP_INCLUDED |
2864 | | #define NANORANGE_ITERATOR_REVERSE_ITERATOR_HPP_INCLUDED |
2865 | | |
2866 | | // nanorange/iterator/operations.hpp |
2867 | | // |
2868 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2869 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2870 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2871 | | |
2872 | | #ifndef NANORANGE_ITERATOR_OPERATIONS_HPP_INCLUDED |
2873 | | #define NANORANGE_ITERATOR_OPERATIONS_HPP_INCLUDED |
2874 | | |
2875 | | // nanorange/detail/ranges/concepts.hpp |
2876 | | // |
2877 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2878 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2879 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2880 | | |
2881 | | #ifndef NANORANGE_DETAIL_RANGES_CONCEPTS_HPP_INCLUDED |
2882 | | #define NANORANGE_DETAIL_RANGES_CONCEPTS_HPP_INCLUDED |
2883 | | |
2884 | | // nanorange/detail/ranges/basic_range_types.hpp |
2885 | | // |
2886 | | // Copyright (c) 2020 Tristan Brindle (tcbrindle at gmail dot com) |
2887 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2888 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2889 | | |
2890 | | #ifndef NANORANGE_DETAIL_RANGES_BASIC_RANGE_TYPES_HPP_INCLUDED |
2891 | | #define NANORANGE_DETAIL_RANGES_BASIC_RANGE_TYPES_HPP_INCLUDED |
2892 | | |
2893 | | // nanorange/detail/ranges/range_concept.hpp |
2894 | | // |
2895 | | // Copyright (c) 2020 Tristan Brindle (tcbrindle at gmail dot com) |
2896 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2897 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2898 | | |
2899 | | #ifndef NANORANGE_DETAIL_RANGES_RANGE_CONCEPT_HPP_INCLUDED |
2900 | | #define NANORANGE_DETAIL_RANGES_RANGE_CONCEPT_HPP_INCLUDED |
2901 | | |
2902 | | NANO_BEGIN_NAMESPACE |
2903 | | |
2904 | | namespace detail { |
2905 | | |
2906 | | struct range_concept { |
2907 | | template <typename T> |
2908 | | auto requires_(T& t) -> decltype(ranges::begin(t), ranges::end(t)); |
2909 | | }; |
2910 | | |
2911 | | } // namespace detail |
2912 | | |
2913 | | template <typename T> |
2914 | | NANO_CONCEPT range = detail::requires_<detail::range_concept, T>; |
2915 | | |
2916 | | NANO_END_NAMESPACE |
2917 | | |
2918 | | #endif |
2919 | | |
2920 | | NANO_BEGIN_NAMESPACE |
2921 | | |
2922 | | template <typename T> |
2923 | | using iterator_t = decltype(ranges::begin(std::declval<T&>())); |
2924 | | |
2925 | | template <typename R> |
2926 | | using sentinel_t = |
2927 | | std::enable_if_t<range<R>, decltype(ranges::end(std::declval<R&>()))>; |
2928 | | |
2929 | | template <typename R> |
2930 | | using range_difference_t = |
2931 | | std::enable_if_t<range<R>, iter_difference_t<iterator_t<R>>>; |
2932 | | |
2933 | | template <typename R> |
2934 | | using range_value_t = std::enable_if_t<range<R>, iter_value_t<iterator_t<R>>>; |
2935 | | |
2936 | | template <typename R> |
2937 | | using range_reference_t = |
2938 | | std::enable_if_t<range<R>, iter_reference_t<iterator_t<R>>>; |
2939 | | |
2940 | | template <typename R> |
2941 | | using range_rvalue_reference_t = |
2942 | | std::enable_if_t<range<R>, iter_rvalue_reference_t<iterator_t<R>>>; |
2943 | | |
2944 | | NANO_END_NAMESPACE |
2945 | | |
2946 | | #endif |
2947 | | |
2948 | | // nanorange/detail/ranges/primitives.hpp |
2949 | | // |
2950 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
2951 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
2952 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2953 | | |
2954 | | #ifndef NANORANGE_DETAIL_RANGES_PRIMITIVES_HPP_INCLUDED |
2955 | | #define NANORANGE_DETAIL_RANGES_PRIMITIVES_HPP_INCLUDED |
2956 | | |
2957 | | NANO_BEGIN_NAMESPACE |
2958 | | |
2959 | | // [range.prim.size] |
2960 | | |
2961 | | template <typename> |
2962 | | inline constexpr bool disable_sized_range = false; |
2963 | | |
2964 | | namespace detail { |
2965 | | namespace size_ { |
2966 | | |
2967 | | template <typename T> |
2968 | | void size(T&&) = delete; |
2969 | | |
2970 | | // For some reason MSVC doesn't mind poison pills, |
2971 | | // as long as there are two |
2972 | | template <typename T> |
2973 | | void size(T&) = delete; |
2974 | | |
2975 | | struct fn { |
2976 | | private: |
2977 | | template <typename T, std::size_t N> |
2978 | | static constexpr std::size_t impl(const T (&&)[N], |
2979 | | priority_tag<3>) noexcept |
2980 | | { |
2981 | | return N; |
2982 | | } |
2983 | | |
2984 | | template <typename T, std::size_t N> |
2985 | | static constexpr std::size_t impl(const T (&)[N], |
2986 | | priority_tag<3>) noexcept |
2987 | | { |
2988 | | return N; |
2989 | | } |
2990 | | |
2991 | | template < |
2992 | | typename T, |
2993 | | typename I = decltype(decay_copy(std::declval<T>().size()))> |
2994 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
2995 | | noexcept(decay_copy(std::forward<T>(t).size()))) |
2996 | | -> std::enable_if_t<integral<I> && |
2997 | | !disable_sized_range<remove_cvref_t<T>>, |
2998 | | I> |
2999 | 70.7M | { |
3000 | 70.7M | return decay_copy(std::forward<T>(t).size()); |
3001 | 70.7M | } std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> const&>::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> const&, long>(nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> const&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 11.7M | { | 3000 | 11.7M | return decay_copy(std::forward<T>(t).size()); | 3001 | 11.7M | } |
std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>&>::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>&, long>(nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 18.4M | { | 3000 | 18.4M | return decay_copy(std::forward<T>(t).size()); | 3001 | 18.4M | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 727k | { | 3000 | 727k | return decay_copy(std::forward<T>(t).size()); | 3001 | 727k | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string_view<char, std::__1::char_traits<char> >&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string_view<char, std::__1::char_traits<char> >&, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 14.2M | { | 3000 | 14.2M | return decay_copy(std::forward<T>(t).size()); | 3001 | 14.2M | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 4.35M | { | 3000 | 4.35M | return decay_copy(std::forward<T>(t).size()); | 3001 | 4.35M | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string_view<char, std::__1::char_traits<char> > const&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string_view<char, std::__1::char_traits<char> > const&, unsigned long>(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 161k | { | 3000 | 161k | return decay_copy(std::forward<T>(t).size()); | 3001 | 161k | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, unsigned long>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 2.70k | { | 3000 | 2.70k | return decay_copy(std::forward<T>(t).size()); | 3001 | 2.70k | } |
Unexecuted instantiation: std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>, long>(nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>&&, nano::ranges::detail::priority_tag<2ul>) std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>&>::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>&, long>(nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 15.5M | { | 3000 | 15.5M | return decay_copy(std::forward<T>(t).size()); | 3001 | 15.5M | } |
std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> > const&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> > const&, unsigned long>(std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> > const&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 141k | { | 3000 | 141k | return decay_copy(std::forward<T>(t).size()); | 3001 | 141k | } |
Unexecuted instantiation: std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>, long>(nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>&&, nano::ranges::detail::priority_tag<2ul>) std::__1::enable_if<(integral<unsigned long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> >&>::type>)), unsigned long>::type nano::ranges::detail::size_::fn::impl<std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> >&, unsigned long>(std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> >&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 36 | { | 3000 | 36 | return decay_copy(std::forward<T>(t).size()); | 3001 | 36 | } |
std::__1::enable_if<(integral<long>)&&(!(disable_sized_range<nano::ranges::remove_cvref<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> const&>::type>)), long>::type nano::ranges::detail::size_::fn::impl<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> const&, long>(nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> const&, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 2999 | 5.31M | { | 3000 | 5.31M | return decay_copy(std::forward<T>(t).size()); | 3001 | 5.31M | } |
|
3002 | | |
3003 | | template < |
3004 | | typename T, |
3005 | | typename I = decltype(decay_copy(size(std::declval<T>())))> |
3006 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
3007 | | noexcept(decay_copy(size(std::forward<T>(t))))) |
3008 | | -> std::enable_if_t<integral<I> && |
3009 | | !disable_sized_range<remove_cvref_t<T>>, |
3010 | | I> |
3011 | | { |
3012 | | return decay_copy(size(std::forward<T>(t))); |
3013 | | } |
3014 | | |
3015 | | template <typename T, |
3016 | | typename I = decltype(ranges::begin(std::declval<T>())), |
3017 | | typename S = decltype(ranges::end(std::declval<T>())), |
3018 | | typename D = decltype(decay_copy(std::declval<S>() - |
3019 | | std::declval<I>()))> |
3020 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
3021 | | noexcept(decay_copy(ranges::end(t) - ranges::begin(t)))) |
3022 | | -> std::enable_if_t< |
3023 | | !std::is_array<remove_cvref_t<T>>::value && // MSVC |
3024 | | // sillyness? |
3025 | | sized_sentinel_for<S, I> && forward_iterator<I>, |
3026 | | D> |
3027 | | { |
3028 | | return decay_copy(ranges::end(t) - ranges::begin(t)); |
3029 | | } |
3030 | | |
3031 | | public: |
3032 | | template <typename T> |
3033 | | constexpr auto operator()(T&& t) const |
3034 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
3035 | | priority_tag<3>{}))) |
3036 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<3>{})) |
3037 | 70.7M | { |
3038 | 70.7M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); |
3039 | 70.7M | } _ZNK4nano6ranges6detail5size_2fnclIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 3037 | 11.7M | { | 3038 | 11.7M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 11.7M | } |
_ZNK4nano6ranges6detail5size_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 3037 | 18.4M | { | 3038 | 18.4M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 18.4M | } |
_ZNK4nano6ranges6detail5size_2fnclIRKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSE_ Line | Count | Source | 3037 | 727k | { | 3038 | 727k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 727k | } |
_ZNK4nano6ranges6detail5size_2fnclIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 3037 | 14.2M | { | 3038 | 14.2M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 14.2M | } |
_ZNK4nano6ranges6detail5size_2fnclIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 3037 | 4.35M | { | 3038 | 4.35M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 4.35M | } |
_ZNK4nano6ranges6detail5size_2fnclIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 3037 | 161k | { | 3038 | 161k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 161k | } |
_ZNK4nano6ranges6detail5size_2fnclIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 3037 | 2.70k | { | 3038 | 2.70k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 2.70k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail5size_2fnclINS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ _ZNK4nano6ranges6detail5size_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 3037 | 15.5M | { | 3038 | 15.5M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 15.5M | } |
_ZNK4nano6ranges6detail5size_2fnclIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSC_ Line | Count | Source | 3037 | 141k | { | 3038 | 141k | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 141k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail5size_2fnclINS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ _ZNK4nano6ranges6detail5size_2fnclIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSB_ Line | Count | Source | 3037 | 36 | { | 3038 | 36 | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 36 | } |
_ZNK4nano6ranges6detail5size_2fnclIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm3EEEEEEOSD_ Line | Count | Source | 3037 | 5.31M | { | 3038 | 5.31M | return fn::impl(std::forward<T>(t), priority_tag<3>{}); | 3039 | 5.31M | } |
|
3040 | | }; |
3041 | | |
3042 | | } // namespace size_ |
3043 | | } // namespace detail |
3044 | | |
3045 | | NANO_INLINE_VAR(detail::size_::fn, size) |
3046 | | |
3047 | | // [range.prim.ssize] |
3048 | | |
3049 | | namespace detail { |
3050 | | namespace ssize_ { |
3051 | | |
3052 | | struct fn { |
3053 | | private: |
3054 | | template <typename T> |
3055 | | using ssize_return_t = |
3056 | | std::conditional_t<sizeof(range_difference_t<T>) < |
3057 | | sizeof(std::ptrdiff_t), |
3058 | | std::ptrdiff_t, |
3059 | | range_difference_t<T>>; |
3060 | | |
3061 | | template <typename T> |
3062 | | static constexpr auto impl(T&& t) noexcept( |
3063 | | noexcept(ranges::size(std::forward<T>(t)))) |
3064 | | -> decltype(ranges::size(std::forward<T>(t)), |
3065 | | ssize_return_t<T>()) |
3066 | 29.7M | { |
3067 | 29.7M | return static_cast<ssize_return_t<T>>( |
3068 | 29.7M | ranges::size(std::forward<T>(t))); |
3069 | 29.7M | } _ZN4nano6ranges6detail6ssize_2fn4implIRKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNS5_11conditionalIXltstNS5_9enable_ifIX5rangeISF_EENS0_20incrementable_traitsIDTclL_ZNSE_5beginEEclsr3stdE7declvalIRSF_EEEEE15difference_typeEE4typeELm8EElSO_E4typeE_EEOSF_ Line | Count | Source | 3066 | 727k | { | 3067 | 727k | return static_cast<ssize_return_t<T>>( | 3068 | 727k | ranges::size(std::forward<T>(t))); | 3069 | 727k | } |
_ZN4nano6ranges6detail6ssize_2fn4implIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNSt3__111conditionalIXltstNSE_9enable_ifIX5rangeISD_EENS0_20incrementable_traitsIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRSD_EEEEE15difference_typeEE4typeELm8EElSN_E4typeE_EEOSD_ Line | Count | Source | 3066 | 92.9k | { | 3067 | 92.9k | return static_cast<ssize_return_t<T>>( | 3068 | 92.9k | ranges::size(std::forward<T>(t))); | 3069 | 92.9k | } |
_ZN4nano6ranges6detail6ssize_2fn4implIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNS5_11conditionalIXltstNS5_9enable_ifIX5rangeISC_EENS0_20incrementable_traitsIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRSC_EEEEE15difference_typeEE4typeELm8EElSL_E4typeE_EEOSC_ Line | Count | Source | 3066 | 13.1M | { | 3067 | 13.1M | return static_cast<ssize_return_t<T>>( | 3068 | 13.1M | ranges::size(std::forward<T>(t))); | 3069 | 13.1M | } |
_ZN4nano6ranges6detail6ssize_2fn4implIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNS5_11conditionalIXltstNS5_9enable_ifIX5rangeISE_EENS0_20incrementable_traitsIDTclL_ZNSD_5beginEEclsr3stdE7declvalIRSE_EEEEE15difference_typeEE4typeELm8EElSN_E4typeE_EEOSE_ Line | Count | Source | 3066 | 4.35M | { | 3067 | 4.35M | return static_cast<ssize_return_t<T>>( | 3068 | 4.35M | ranges::size(std::forward<T>(t))); | 3069 | 4.35M | } |
_ZN4nano6ranges6detail6ssize_2fn4implIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNSt3__111conditionalIXltstNSE_9enable_ifIX5rangeISD_EENS0_20incrementable_traitsIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRSD_EEEEE15difference_typeEE4typeELm8EElSN_E4typeE_EEOSD_ Line | Count | Source | 3066 | 11.4M | { | 3067 | 11.4M | return static_cast<ssize_return_t<T>>( | 3068 | 11.4M | ranges::size(std::forward<T>(t))); | 3069 | 11.4M | } |
_ZN4nano6ranges6detail6ssize_2fn4implIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTcmclL_ZNS0_16function_objects4sizeEEclsr3stdE7forwardIT_Efp_EEcvNS5_11conditionalIXltstNS5_9enable_ifIX5rangeISC_EENS0_20incrementable_traitsIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRSC_EEEEE15difference_typeEE4typeELm8EElSL_E4typeE_EEOSC_ Line | Count | Source | 3066 | 36 | { | 3067 | 36 | return static_cast<ssize_return_t<T>>( | 3068 | 36 | ranges::size(std::forward<T>(t))); | 3069 | 36 | } |
|
3070 | | |
3071 | | public: |
3072 | | template <typename T> |
3073 | | constexpr auto operator()(T&& t) const |
3074 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
3075 | | -> decltype(fn::impl(std::forward<T>(t))) |
3076 | 29.7M | { |
3077 | 29.7M | return fn::impl(std::forward<T>(t)); |
3078 | 29.7M | } _ZNK4nano6ranges6detail6ssize_2fnclIRKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSE_ Line | Count | Source | 3076 | 727k | { | 3077 | 727k | return fn::impl(std::forward<T>(t)); | 3078 | 727k | } |
_ZNK4nano6ranges6detail6ssize_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSC_ Line | Count | Source | 3076 | 92.9k | { | 3077 | 92.9k | return fn::impl(std::forward<T>(t)); | 3078 | 92.9k | } |
_ZNK4nano6ranges6detail6ssize_2fnclIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSB_ Line | Count | Source | 3076 | 13.1M | { | 3077 | 13.1M | return fn::impl(std::forward<T>(t)); | 3078 | 13.1M | } |
_ZNK4nano6ranges6detail6ssize_2fnclIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSD_ Line | Count | Source | 3076 | 4.35M | { | 3077 | 4.35M | return fn::impl(std::forward<T>(t)); | 3078 | 4.35M | } |
_ZNK4nano6ranges6detail6ssize_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSC_ Line | Count | Source | 3076 | 11.4M | { | 3077 | 11.4M | return fn::impl(std::forward<T>(t)); | 3078 | 11.4M | } |
_ZNK4nano6ranges6detail6ssize_2fnclIRNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EEEOSB_ Line | Count | Source | 3076 | 36 | { | 3077 | 36 | return fn::impl(std::forward<T>(t)); | 3078 | 36 | } |
|
3079 | | }; |
3080 | | |
3081 | | } // namespace ssize_ |
3082 | | } // namespace detail |
3083 | | |
3084 | | NANO_INLINE_VAR(detail::ssize_::fn, ssize) |
3085 | | |
3086 | | // [range.prim.empty] |
3087 | | |
3088 | | namespace detail { |
3089 | | namespace empty_ { |
3090 | | |
3091 | | struct fn { |
3092 | | private: |
3093 | | template <typename T> |
3094 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
3095 | | noexcept((bool(std::forward<T>(t).empty())))) |
3096 | | -> decltype((bool(std::forward<T>(t).empty()))) |
3097 | 39.4M | { |
3098 | 39.4M | return bool((std::forward<T>(t).empty())); |
3099 | 39.4M | } _ZN4nano6ranges6detail6empty_2fn4implIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTcvbcldtclsr3stdE7forwardIT_Efp_E5emptyEEOSD_NS1_12priority_tagILm2EEE Line | Count | Source | 3097 | 11.7M | { | 3098 | 11.7M | return bool((std::forward<T>(t).empty())); | 3099 | 11.7M | } |
_ZN4nano6ranges6detail6empty_2fn4implIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTcvbcldtclsr3stdE7forwardIT_Efp_E5emptyEEOSC_NS1_12priority_tagILm2EEE Line | Count | Source | 3097 | 18.3M | { | 3098 | 18.3M | return bool((std::forward<T>(t).empty())); | 3099 | 18.3M | } |
_ZN4nano6ranges6detail6empty_2fn4implIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTcvbcldtclsr3stdE7forwardIT_Efp_E5emptyEEOSC_NS1_12priority_tagILm2EEE Line | Count | Source | 3097 | 4.09M | { | 3098 | 4.09M | return bool((std::forward<T>(t).empty())); | 3099 | 4.09M | } |
_ZN4nano6ranges6detail6empty_2fn4implIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTcvbcldtclsr3stdE7forwardIT_Efp_E5emptyEEOSD_NS1_12priority_tagILm2EEE Line | Count | Source | 3097 | 5.31M | { | 3098 | 5.31M | return bool((std::forward<T>(t).empty())); | 3099 | 5.31M | } |
|
3100 | | |
3101 | | template <typename T> |
3102 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
3103 | | noexcept(ranges::size(std::forward<T>(t)) == 0)) |
3104 | | -> decltype(ranges::size(std::forward<T>(t)) == 0) |
3105 | | { |
3106 | | return ranges::size(std::forward<T>(t)) == 0; |
3107 | | } |
3108 | | |
3109 | | template <typename T, |
3110 | | typename I = decltype(ranges::begin(std::declval<T>()))> |
3111 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
3112 | | noexcept(ranges::begin(t) == ranges::end(t))) |
3113 | | -> std::enable_if_t<forward_iterator<I>, |
3114 | | decltype(ranges::begin(t) == |
3115 | | ranges::end(t))> |
3116 | | { |
3117 | | return ranges::begin(t) == ranges::end(t); |
3118 | | } |
3119 | | |
3120 | | public: |
3121 | | template <typename T> |
3122 | | constexpr auto operator()(T&& t) const |
3123 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
3124 | | priority_tag<2>{}))) |
3125 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<2>{})) |
3126 | 39.4M | { |
3127 | 39.4M | return fn::impl(std::forward<T>(t), priority_tag<2>{}); |
3128 | 39.4M | } _ZNK4nano6ranges6detail6empty_2fnclIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm2EEEEEEOSD_ Line | Count | Source | 3126 | 11.7M | { | 3127 | 11.7M | return fn::impl(std::forward<T>(t), priority_tag<2>{}); | 3128 | 11.7M | } |
_ZNK4nano6ranges6detail6empty_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm2EEEEEEOSC_ Line | Count | Source | 3126 | 18.3M | { | 3127 | 18.3M | return fn::impl(std::forward<T>(t), priority_tag<2>{}); | 3128 | 18.3M | } |
_ZNK4nano6ranges6detail6empty_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm2EEEEEEOSC_ Line | Count | Source | 3126 | 4.09M | { | 3127 | 4.09M | return fn::impl(std::forward<T>(t), priority_tag<2>{}); | 3128 | 4.09M | } |
_ZNK4nano6ranges6detail6empty_2fnclIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm2EEEEEEOSD_ Line | Count | Source | 3126 | 5.31M | { | 3127 | 5.31M | return fn::impl(std::forward<T>(t), priority_tag<2>{}); | 3128 | 5.31M | } |
|
3129 | | }; |
3130 | | |
3131 | | } // namespace empty_ |
3132 | | } // namespace detail |
3133 | | |
3134 | | NANO_INLINE_VAR(detail::empty_::fn, empty) |
3135 | | |
3136 | | namespace detail { |
3137 | | |
3138 | | template <typename, typename = void> |
3139 | | inline constexpr bool is_object_pointer_v = false; |
3140 | | |
3141 | | template <typename P> |
3142 | | inline constexpr bool is_object_pointer_v< |
3143 | | P, |
3144 | | std::enable_if_t<std::is_pointer_v<P> && |
3145 | | std::is_object_v<iter_value_t<P>>>> = true; |
3146 | | |
3147 | | namespace data_ { |
3148 | | |
3149 | | struct fn { |
3150 | | private: |
3151 | | template < |
3152 | | typename T, |
3153 | | typename D = decltype(decay_copy(std::declval<T&>().data()))> |
3154 | | static constexpr auto impl(T& t, priority_tag<1>) noexcept( |
3155 | | noexcept(decay_copy(t.data()))) |
3156 | | -> std::enable_if_t<is_object_pointer_v<D>, D> |
3157 | 40.8M | { |
3158 | 40.8M | return t.data(); |
3159 | 40.8M | } std::__1::enable_if<is_object_pointer_v<char const*>, char const*>::type nano::ranges::detail::data_::fn::impl<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> const, char const*>(nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> const&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 11.7M | { | 3158 | 11.7M | return t.data(); | 3159 | 11.7M | } |
std::__1::enable_if<is_object_pointer_v<char const*>, char const*>::type nano::ranges::detail::data_::fn::impl<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>, char const*>(nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 18.2M | { | 3158 | 18.2M | return t.data(); | 3159 | 18.2M | } |
std::__1::enable_if<is_object_pointer_v<char const*>, char const*>::type nano::ranges::detail::data_::fn::impl<std::__1::basic_string_view<char, std::__1::char_traits<char> > const, char const*>(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 161k | { | 3158 | 161k | return t.data(); | 3159 | 161k | } |
std::__1::enable_if<is_object_pointer_v<wchar_t*>, wchar_t*>::type nano::ranges::detail::data_::fn::impl<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, wchar_t*>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 5.40k | { | 3158 | 5.40k | return t.data(); | 3159 | 5.40k | } |
std::__1::enable_if<is_object_pointer_v<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::data_::fn::impl<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>, wchar_t const*>(nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 4.08M | { | 3158 | 4.08M | return t.data(); | 3159 | 4.08M | } |
std::__1::enable_if<is_object_pointer_v<char*>, char*>::type nano::ranges::detail::data_::fn::impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 5.50k | { | 3158 | 5.50k | return t.data(); | 3159 | 5.50k | } |
std::__1::enable_if<is_object_pointer_v<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::data_::fn::impl<std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> > const, wchar_t const*>(std::__1::basic_string_view<wchar_t, std::__1::char_traits<wchar_t> > const&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 141k | { | 3158 | 141k | return t.data(); | 3159 | 141k | } |
std::__1::enable_if<is_object_pointer_v<char const*>, char const*>::type nano::ranges::detail::data_::fn::impl<std::__1::basic_string_view<char, std::__1::char_traits<char> >, char const*>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 1.14M | { | 3158 | 1.14M | return t.data(); | 3159 | 1.14M | } |
std::__1::enable_if<is_object_pointer_v<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::data_::fn::impl<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> const, wchar_t const*>(nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> const&, nano::ranges::detail::priority_tag<1ul>) Line | Count | Source | 3157 | 5.31M | { | 3158 | 5.31M | return t.data(); | 3159 | 5.31M | } |
|
3160 | | |
3161 | | template <typename T> |
3162 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
3163 | | noexcept(ranges::begin(std::forward<T>(t)))) |
3164 | | -> std::enable_if_t<is_object_pointer_v<decltype(ranges::begin( |
3165 | | std::forward<T>(t)))>, |
3166 | | decltype(ranges::begin(std::forward<T>(t)))> |
3167 | 0 | { |
3168 | 0 | return ranges::begin(std::forward<T>(t)); |
3169 | 0 | } Unexecuted instantiation: _ZN4nano6ranges6detail5data_2fn4implINS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX19is_object_pointer_vIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7forwardIT_Efp_EEEEESF_E4typeEOSE_NS1_12priority_tagILm0EEE Unexecuted instantiation: _ZN4nano6ranges6detail5data_2fn4implINS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEENSt3__19enable_ifIX19is_object_pointer_vIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7forwardIT_Efp_EEEEESF_E4typeEOSE_NS1_12priority_tagILm0EEE |
3170 | | |
3171 | | public: |
3172 | | template <typename T> |
3173 | | constexpr auto operator()(T&& t) const |
3174 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
3175 | | priority_tag<1>{}))) |
3176 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<1>{})) |
3177 | 40.8M | { |
3178 | 40.8M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); |
3179 | 40.8M | } _ZNK4nano6ranges6detail5data_2fnclIRKNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSD_ Line | Count | Source | 3177 | 11.7M | { | 3178 | 11.7M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 11.7M | } |
_ZNK4nano6ranges6detail5data_2fnclIRNS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSC_ Line | Count | Source | 3177 | 18.2M | { | 3178 | 18.2M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 18.2M | } |
_ZNK4nano6ranges6detail5data_2fnclIRKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSC_ Line | Count | Source | 3177 | 161k | { | 3178 | 161k | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 161k | } |
_ZNK4nano6ranges6detail5data_2fnclIRNSt3__112basic_stringIwNS5_11char_traitsIwEENS5_9allocatorIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSD_ Line | Count | Source | 3177 | 5.40k | { | 3178 | 5.40k | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 5.40k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail5data_2fnclINS0_9subrange_8subrangeIPKcS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSB_ _ZNK4nano6ranges6detail5data_2fnclIRNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSC_ Line | Count | Source | 3177 | 4.08M | { | 3178 | 4.08M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 4.08M | } |
_ZNK4nano6ranges6detail5data_2fnclIRNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSD_ Line | Count | Source | 3177 | 5.50k | { | 3178 | 5.50k | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 5.50k | } |
_ZNK4nano6ranges6detail5data_2fnclIRKNSt3__117basic_string_viewIwNS5_11char_traitsIwEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSC_ Line | Count | Source | 3177 | 141k | { | 3178 | 141k | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 141k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail5data_2fnclINS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSB_ _ZNK4nano6ranges6detail5data_2fnclIRNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSB_ Line | Count | Source | 3177 | 1.14M | { | 3178 | 1.14M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 1.14M | } |
_ZNK4nano6ranges6detail5data_2fnclIRKNS0_9subrange_8subrangeIPKwS8_LNS0_13subrange_kindE1EEEEEDTclsr2fnE4implclsr3stdE7forwardIT_Efp_EtlNS1_12priority_tagILm1EEEEEEOSD_ Line | Count | Source | 3177 | 5.31M | { | 3178 | 5.31M | return fn::impl(std::forward<T>(t), priority_tag<1>{}); | 3179 | 5.31M | } |
|
3180 | | }; |
3181 | | |
3182 | | } // namespace data_ |
3183 | | } // namespace detail |
3184 | | |
3185 | | NANO_INLINE_VAR(detail::data_::fn, data) |
3186 | | |
3187 | | namespace detail { |
3188 | | namespace cdata_ { |
3189 | | |
3190 | | struct fn { |
3191 | | private: |
3192 | | template <typename T, |
3193 | | typename U = std::remove_reference_t<T>, |
3194 | | std::enable_if_t<std::is_lvalue_reference_v<T>, int> = 0> |
3195 | | static constexpr auto impl(T&& t) noexcept( |
3196 | | noexcept(ranges::data(static_cast<const U&>(t)))) |
3197 | | -> decltype(ranges::data(static_cast<const U&>(t))) |
3198 | | { |
3199 | | return ranges::data(static_cast<const U&>(t)); |
3200 | | } |
3201 | | |
3202 | | template <typename T, |
3203 | | std::enable_if_t<!std::is_lvalue_reference_v<T>, int> = 0> |
3204 | | static constexpr auto impl(T&& t) noexcept( |
3205 | | noexcept(ranges::data(static_cast<const T&&>(t)))) |
3206 | | -> decltype(ranges::data(static_cast<const T&&>(t))) |
3207 | | { |
3208 | | return ranges::data(static_cast<const T&&>(t)); |
3209 | | } |
3210 | | |
3211 | | public: |
3212 | | template <typename T> |
3213 | | constexpr auto operator()(T&& t) const |
3214 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
3215 | | -> decltype(fn::impl(std::forward<T>(t))) |
3216 | | { |
3217 | | return fn::impl(std::forward<T>(t)); |
3218 | | } |
3219 | | }; |
3220 | | |
3221 | | } // namespace cdata_ |
3222 | | } // namespace detail |
3223 | | |
3224 | | NANO_INLINE_VAR(detail::cdata_::fn, cdata) |
3225 | | |
3226 | | NANO_END_NAMESPACE |
3227 | | |
3228 | | #endif |
3229 | | |
3230 | | #include <initializer_list> |
3231 | | |
3232 | | // Avoid dragging in the large <set> and <unordered_set> headers |
3233 | | // This is technically undefined behaviour: define the symbol |
3234 | | // NANORANGE_NO_STD_FORWARD_DECLARATIONS |
3235 | | // to enforce standard-compliant mode |
3236 | | #ifndef NANORANGE_NO_STD_FORWARD_DECLARATIONS |
3237 | | NANO_BEGIN_NAMESPACE_STD |
3238 | | template <typename, typename> |
3239 | | class basic_string_view; |
3240 | | template <typename, typename, typename> |
3241 | | class set; |
3242 | | template <typename, typename, typename> |
3243 | | class multiset; |
3244 | | template <typename, typename, typename, typename> |
3245 | | class unordered_set; |
3246 | | template <typename, typename, typename, typename> |
3247 | | class unordered_multiset; |
3248 | | template <typename, typename> |
3249 | | class match_results; |
3250 | | NANO_END_NAMESPACE_STD |
3251 | | #else |
3252 | | #include <regex> |
3253 | | #include <set> |
3254 | | #include <string_view> |
3255 | | #include <unordered_set> |
3256 | | #endif |
3257 | | |
3258 | | NANO_BEGIN_NAMESPACE |
3259 | | |
3260 | | template <typename T> |
3261 | | NANO_CONCEPT borrowed_range = |
3262 | | range<T> && |
3263 | | (std::is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>); |
3264 | | |
3265 | | // Special-case std::string_view |
3266 | | template <typename CharT, typename Traits> |
3267 | | inline constexpr bool |
3268 | | enable_borrowed_range<std::basic_string_view<CharT, Traits>> = true; |
3269 | | |
3270 | | // [range.sized] |
3271 | | namespace detail { |
3272 | | |
3273 | | struct sized_range_concept { |
3274 | | template <typename T> |
3275 | | auto requires_(T& t) -> decltype(ranges::size(t)); |
3276 | | }; |
3277 | | |
3278 | | } // namespace detail |
3279 | | |
3280 | | template <typename T> |
3281 | | NANO_CONCEPT sized_range = |
3282 | | range<T> && !disable_sized_range<remove_cvref_t<T>> && |
3283 | | detail::requires_<detail::sized_range_concept, T>; |
3284 | | |
3285 | | // [range.views] |
3286 | | struct view_base {}; |
3287 | | |
3288 | | namespace detail { |
3289 | | |
3290 | | template <typename> |
3291 | | inline constexpr bool is_std_non_view = false; |
3292 | | |
3293 | | template <typename T> |
3294 | | inline constexpr bool is_std_non_view<std::initializer_list<T>> = true; |
3295 | | |
3296 | | template <typename K, typename C, typename A> |
3297 | | inline constexpr bool is_std_non_view<std::set<K, C, A>> = true; |
3298 | | |
3299 | | template <typename K, typename C, typename A> |
3300 | | inline constexpr bool is_std_non_view<std::multiset<K, C, A>> = true; |
3301 | | |
3302 | | template <typename K, typename H, typename E, typename A> |
3303 | | inline constexpr bool is_std_non_view<std::unordered_set<K, H, E, A>> = |
3304 | | true; |
3305 | | |
3306 | | template <typename K, typename H, typename E, typename A> |
3307 | | inline constexpr bool is_std_non_view<std::unordered_multiset<K, H, E, A>> = |
3308 | | true; |
3309 | | |
3310 | | template <typename B, typename A> |
3311 | | inline constexpr bool is_std_non_view<std::match_results<B, A>> = true; |
3312 | | |
3313 | | template <typename T> |
3314 | | constexpr bool enable_view_helper() |
3315 | 0 | { |
3316 | 0 | if constexpr (derived_from<T, view_base>) { |
3317 | 0 | return true; |
3318 | 0 | } |
3319 | 0 | else if constexpr (is_std_non_view<T>) { |
3320 | 0 | return false; |
3321 | 0 | } |
3322 | 0 | else if constexpr (range<T> && range<const T>) { |
3323 | 0 | return same_as<range_reference_t<T>, range_reference_t<const T>>; |
3324 | 0 | } |
3325 | 0 | else { |
3326 | 0 | return true; |
3327 | 0 | } |
3328 | 0 | } Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<std::__1::basic_string_view<char, std::__1::char_traits<char> > >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, (nano::ranges::subrange_kind)1> >() Unexecuted instantiation: bool nano::ranges::detail::enable_view_helper<nano::ranges::subrange_::subrange<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, (nano::ranges::subrange_kind)1> >() |
3329 | | |
3330 | | } // namespace detail |
3331 | | |
3332 | | template <typename T> |
3333 | | inline constexpr bool enable_view = detail::enable_view_helper<T>(); |
3334 | | |
3335 | | // CHANGED: |
3336 | | // semiregular<T> -> movable<T> |
3337 | | template <typename T> |
3338 | | NANO_CONCEPT view = range<T> && movable<T> && enable_view<T>; |
3339 | | |
3340 | | // [range.refinements] |
3341 | | namespace detail { |
3342 | | |
3343 | | struct output_range_concept { |
3344 | | template <typename, typename> |
3345 | | static auto test(long) -> std::false_type; |
3346 | | |
3347 | | template <typename R, typename T> |
3348 | | static auto test(int) |
3349 | | -> std::enable_if_t<range<R> && output_iterator<iterator_t<R>, T>, |
3350 | | std::true_type>; |
3351 | | }; |
3352 | | |
3353 | | } // namespace detail |
3354 | | |
3355 | | template <typename R, typename T> |
3356 | | NANO_CONCEPT output_range = |
3357 | | decltype(detail::output_range_concept::test<R, T>(0))::value; |
3358 | | |
3359 | | namespace detail { |
3360 | | |
3361 | | struct input_range_concept { |
3362 | | template <typename> |
3363 | | static auto test(long) -> std::false_type; |
3364 | | |
3365 | | template <typename T> |
3366 | | static auto test(int) |
3367 | | -> std::enable_if_t<range<T> && input_iterator<iterator_t<T>>, |
3368 | | std::true_type>; |
3369 | | }; |
3370 | | |
3371 | | } // namespace detail |
3372 | | |
3373 | | template <typename T> |
3374 | | NANO_CONCEPT input_range = |
3375 | | decltype(detail::input_range_concept::test<T>(0))::value; |
3376 | | |
3377 | | namespace detail { |
3378 | | |
3379 | | struct forward_range_concept { |
3380 | | template <typename> |
3381 | | static auto test(long) -> std::false_type; |
3382 | | |
3383 | | template <typename T> |
3384 | | static auto test(int) |
3385 | | -> std::enable_if_t<input_range<T> && |
3386 | | forward_iterator<iterator_t<T>>, |
3387 | | std::true_type>; |
3388 | | }; |
3389 | | |
3390 | | } // namespace detail |
3391 | | |
3392 | | template <typename T> |
3393 | | NANO_CONCEPT forward_range = |
3394 | | decltype(detail::forward_range_concept::test<T>(0))::value; |
3395 | | |
3396 | | namespace detail { |
3397 | | |
3398 | | struct bidirectional_range_concept { |
3399 | | template <typename> |
3400 | | static auto test(long) -> std::false_type; |
3401 | | |
3402 | | template <typename T> |
3403 | | static auto test(int) |
3404 | | -> std::enable_if_t<forward_range<T> && |
3405 | | bidirectional_iterator<iterator_t<T>>, |
3406 | | std::true_type>; |
3407 | | }; |
3408 | | |
3409 | | } // namespace detail |
3410 | | |
3411 | | template <typename T> |
3412 | | NANO_CONCEPT bidirectional_range = |
3413 | | decltype(detail::bidirectional_range_concept::test<T>(0))::value; |
3414 | | |
3415 | | namespace detail { |
3416 | | |
3417 | | struct random_access_range_concept { |
3418 | | template <typename> |
3419 | | static auto test(long) -> std::false_type; |
3420 | | |
3421 | | template <typename T> |
3422 | | static auto test(int) |
3423 | | -> std::enable_if_t<bidirectional_range<T> && |
3424 | | random_access_iterator<iterator_t<T>>, |
3425 | | std::true_type>; |
3426 | | }; |
3427 | | |
3428 | | } // namespace detail |
3429 | | |
3430 | | template <typename T> |
3431 | | NANO_CONCEPT random_access_range = |
3432 | | decltype(detail::random_access_range_concept::test<T>(0))::value; |
3433 | | |
3434 | | namespace detail { |
3435 | | |
3436 | | // FIXME: Not to spec |
3437 | | // We only require random_access_iterator, not contiguous_iterator |
3438 | | // This is so that vector::iterator, string::iterator etc can model |
3439 | | // contiguous_range. |
3440 | | // If we do range-v3-style deep integration with iterator_traits then |
3441 | | // this could be fixed |
3442 | | struct contiguous_range_concept { |
3443 | | template <typename> |
3444 | | static auto test(long) -> std::false_type; |
3445 | | |
3446 | | template <typename T> |
3447 | | static auto test(int) -> std::enable_if_t< |
3448 | | random_access_range<T> && /* contiguous_iterator<iterator_t<T>> && |
3449 | | */ |
3450 | | detail::requires_<contiguous_range_concept, T>, |
3451 | | std::true_type>; |
3452 | | |
3453 | | template <typename T> |
3454 | | auto requires_(T& t) |
3455 | | -> decltype(requires_expr< |
3456 | | same_as<decltype(ranges::data(t)), |
3457 | | std::add_pointer_t<range_reference_t<T>>>>{}); |
3458 | | }; |
3459 | | |
3460 | | } // namespace detail |
3461 | | |
3462 | | template <typename R> |
3463 | | NANO_CONCEPT contiguous_range = |
3464 | | decltype(detail::contiguous_range_concept::test<R>(0))::value; |
3465 | | |
3466 | | namespace detail { |
3467 | | |
3468 | | struct common_range_concept { |
3469 | | template <typename> |
3470 | | static auto test(long) -> std::false_type; |
3471 | | |
3472 | | template <typename T> |
3473 | | static auto test(int) |
3474 | | -> std::enable_if_t<range<T> && |
3475 | | same_as<iterator_t<T>, sentinel_t<T>>, |
3476 | | std::true_type>; |
3477 | | }; |
3478 | | |
3479 | | } // namespace detail |
3480 | | |
3481 | | template <typename T> |
3482 | | NANO_CONCEPT common_range = |
3483 | | decltype(detail::common_range_concept::test<T>(0))::value; |
3484 | | |
3485 | | template <typename T> |
3486 | | NANO_CONCEPT viewable_range = |
3487 | | range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>); |
3488 | | |
3489 | | // [range.dangling] |
3490 | | |
3491 | | struct dangling { |
3492 | | constexpr dangling() noexcept = default; |
3493 | | |
3494 | | template <typename... Args> |
3495 | | constexpr dangling(Args&&...) noexcept |
3496 | | { |
3497 | | } |
3498 | | }; |
3499 | | |
3500 | | template <typename R> |
3501 | | using borrowed_iterator_t = |
3502 | | detail::conditional_t<borrowed_range<R>, iterator_t<R>, dangling>; |
3503 | | |
3504 | | // Helper concepts |
3505 | | |
3506 | | namespace detail { |
3507 | | |
3508 | | struct simple_view_concept { |
3509 | | template <typename> |
3510 | | static auto test(long) -> std::false_type; |
3511 | | |
3512 | | template <typename R> |
3513 | | static auto test(int) -> std::enable_if_t< |
3514 | | view<R> && range<const R> && |
3515 | | same_as<iterator_t<R>, iterator_t<const R>> && |
3516 | | same_as<sentinel_t<R>, sentinel_t<const R>>, |
3517 | | std::true_type>; |
3518 | | }; |
3519 | | |
3520 | | template <typename R> |
3521 | | NANO_CONCEPT simple_view = decltype(simple_view_concept::test<R>(0))::value; |
3522 | | |
3523 | | struct has_arrow_concept { |
3524 | | template <typename I> |
3525 | | auto requires_(I i) -> decltype(i.operator->()); |
3526 | | }; |
3527 | | |
3528 | | template <typename I> |
3529 | | NANO_CONCEPT has_arrow = |
3530 | | input_iterator<I> && |
3531 | | (std::is_pointer_v<I> || detail::requires_<has_arrow_concept, I>); |
3532 | | |
3533 | | template <typename T, typename U> |
3534 | | NANO_CONCEPT not_same_as = !same_as<remove_cvref_t<T>, remove_cvref_t<U>>; |
3535 | | |
3536 | | } // namespace detail |
3537 | | |
3538 | | NANO_END_NAMESPACE |
3539 | | |
3540 | | #endif |
3541 | | |
3542 | | NANO_BEGIN_NAMESPACE |
3543 | | |
3544 | | namespace detail { |
3545 | | namespace advance_ { |
3546 | | |
3547 | | struct fn { |
3548 | | private: |
3549 | | template <typename T> |
3550 | | static constexpr T abs(T t) |
3551 | 52.4k | { |
3552 | 52.4k | if (t < T{0}) { |
3553 | 0 | return -t; |
3554 | 0 | } |
3555 | 52.4k | return t; |
3556 | 52.4k | } |
3557 | | |
3558 | | template <typename R> |
3559 | | static constexpr auto impl(R& r, iter_difference_t<R> n) |
3560 | | -> std::enable_if_t<random_access_iterator<R>> |
3561 | 42.1M | { |
3562 | 42.1M | r += n; |
3563 | 42.1M | } std::__1::enable_if<random_access_iterator<char const*>, void>::type nano::ranges::detail::advance_::fn::impl<char const*>(char const*&, nano::ranges::incrementable_traits<char const*>::difference_type) Line | Count | Source | 3561 | 20.3M | { | 3562 | 20.3M | r += n; | 3563 | 20.3M | } |
std::__1::enable_if<random_access_iterator<wchar_t const*>, void>::type nano::ranges::detail::advance_::fn::impl<wchar_t const*>(wchar_t const*&, nano::ranges::incrementable_traits<wchar_t const*>::difference_type) Line | Count | Source | 3561 | 21.7M | { | 3562 | 21.7M | r += n; | 3563 | 21.7M | } |
std::__1::enable_if<random_access_iterator<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >, void>::type nano::ranges::detail::advance_::fn::impl<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >(std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>&, nano::ranges::incrementable_traits<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >::difference_type) Line | Count | Source | 3561 | 1.41k | { | 3562 | 1.41k | r += n; | 3563 | 1.41k | } |
std::__1::enable_if<random_access_iterator<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >, void>::type nano::ranges::detail::advance_::fn::impl<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >(std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>&, nano::ranges::incrementable_traits<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >::difference_type) Line | Count | Source | 3561 | 33.5k | { | 3562 | 33.5k | r += n; | 3563 | 33.5k | } |
|
3564 | | |
3565 | | template <typename I> |
3566 | | static constexpr auto impl(I& i, iter_difference_t<I> n) |
3567 | | -> std::enable_if_t<bidirectional_iterator<I> && |
3568 | | !random_access_iterator<I>> |
3569 | 834 | { |
3570 | 834 | constexpr auto zero = iter_difference_t<I>{0}; |
3571 | | |
3572 | 834 | if (n > zero) { |
3573 | 0 | while (n-- > zero) { |
3574 | 0 | ++i; |
3575 | 0 | } |
3576 | 0 | } |
3577 | 834 | else { |
3578 | 834 | while (n++ < zero) { |
3579 | 0 | --i; |
3580 | 0 | } |
3581 | 834 | } |
3582 | 834 | } std::__1::enable_if<(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(!(random_access_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type) Line | Count | Source | 3569 | 834 | { | 3570 | 834 | constexpr auto zero = iter_difference_t<I>{0}; | 3571 | | | 3572 | 834 | if (n > zero) { | 3573 | 0 | while (n-- > zero) { | 3574 | 0 | ++i; | 3575 | 0 | } | 3576 | 0 | } | 3577 | 834 | else { | 3578 | 834 | while (n++ < zero) { | 3579 | 0 | --i; | 3580 | 0 | } | 3581 | 834 | } | 3582 | 834 | } |
Unexecuted instantiation: std::__1::enable_if<(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(!(random_access_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type) |
3583 | | |
3584 | | template <typename I> |
3585 | | static constexpr auto impl(I& i, iter_difference_t<I> n) |
3586 | | -> std::enable_if_t<!bidirectional_iterator<I>> |
3587 | 0 | { |
3588 | 0 | while (n-- > iter_difference_t<I>{0}) { |
3589 | 0 | ++i; |
3590 | 0 | } |
3591 | 0 | } Unexecuted instantiation: std::__1::enable_if<!(bidirectional_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type) Unexecuted instantiation: std::__1::enable_if<!(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) Unexecuted instantiation: std::__1::enable_if<!(bidirectional_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type) Unexecuted instantiation: std::__1::enable_if<!(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), void>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) |
3592 | | |
3593 | | template <typename I, typename S> |
3594 | | static constexpr auto impl(I& i, S bound, priority_tag<2>) |
3595 | | -> std::enable_if_t<assignable_from<I&, S>> |
3596 | 3.16M | { |
3597 | 3.16M | i = std::move(bound); |
3598 | 3.16M | } std::__1::enable_if<assignable_from<char const*&, char const*>, void>::type nano::ranges::detail::advance_::fn::impl<char const*, char const*>(char const*&, char const*, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 3596 | 1.67M | { | 3597 | 1.67M | i = std::move(bound); | 3598 | 1.67M | } |
std::__1::enable_if<assignable_from<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>&, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >, void>::type nano::ranges::detail::advance_::fn::impl<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>&, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 3596 | 6.99k | { | 3597 | 6.99k | i = std::move(bound); | 3598 | 6.99k | } |
std::__1::enable_if<assignable_from<wchar_t const*&, wchar_t const*>, void>::type nano::ranges::detail::advance_::fn::impl<wchar_t const*, wchar_t const*>(wchar_t const*&, wchar_t const*, nano::ranges::detail::priority_tag<2ul>) Line | Count | Source | 3596 | 1.48M | { | 3597 | 1.48M | i = std::move(bound); | 3598 | 1.48M | } |
|
3599 | | |
3600 | | template <typename I, typename S> |
3601 | | static constexpr auto impl(I& i, S bound, priority_tag<1>) |
3602 | | -> std::enable_if_t<sized_sentinel_for<S, I>> |
3603 | | { |
3604 | | fn::impl(i, bound - i); |
3605 | | } |
3606 | | |
3607 | | template <typename I, typename S> |
3608 | | static constexpr void impl(I& i, S bound, priority_tag<0>) |
3609 | 47.4k | { |
3610 | 191M | while (i != bound) { |
3611 | 191M | ++i; |
3612 | 191M | } |
3613 | 47.4k | } void nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, nano::ranges::detail::priority_tag<0ul>) Line | Count | Source | 3609 | 20.9k | { | 3610 | 1.50M | while (i != bound) { | 3611 | 1.48M | ++i; | 3612 | 1.48M | } | 3613 | 20.9k | } |
void nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, nano::ranges::detail::priority_tag<0ul>) Line | Count | Source | 3609 | 1.40k | { | 3610 | 71.5M | while (i != bound) { | 3611 | 71.5M | ++i; | 3612 | 71.5M | } | 3613 | 1.40k | } |
void nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, nano::ranges::detail::priority_tag<0ul>) Line | Count | Source | 3609 | 20.4k | { | 3610 | 1.18M | while (i != bound) { | 3611 | 1.16M | ++i; | 3612 | 1.16M | } | 3613 | 20.4k | } |
void nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, nano::ranges::detail::priority_tag<0ul>) Line | Count | Source | 3609 | 4.62k | { | 3610 | 116M | while (i != bound) { | 3611 | 116M | ++i; | 3612 | 116M | } | 3613 | 4.62k | } |
|
3614 | | |
3615 | | template <typename I, typename S> |
3616 | | static constexpr auto impl(I& i, iter_difference_t<I> n, S bound) |
3617 | | -> std::enable_if_t<sized_sentinel_for<S, I>, |
3618 | | iter_difference_t<I>> |
3619 | 26.2k | { |
3620 | 26.2k | if (fn::abs(n) >= fn::abs(bound - i)) { |
3621 | 3.84k | auto dist = bound - i; |
3622 | 3.84k | fn::impl(i, bound, priority_tag<2>{}); |
3623 | 3.84k | return dist; |
3624 | 3.84k | } |
3625 | 22.3k | else { |
3626 | 22.3k | fn::impl(i, n); |
3627 | 22.3k | return n; |
3628 | 22.3k | } |
3629 | 26.2k | } std::__1::enable_if<sized_sentinel_for<char const*, char const*>, nano::ranges::incrementable_traits<char const*>::difference_type>::type nano::ranges::detail::advance_::fn::impl<char const*, char const*>(char const*&, nano::ranges::incrementable_traits<char const*>::difference_type, char const*) Line | Count | Source | 3619 | 26.2k | { | 3620 | 26.2k | if (fn::abs(n) >= fn::abs(bound - i)) { | 3621 | 3.84k | auto dist = bound - i; | 3622 | 3.84k | fn::impl(i, bound, priority_tag<2>{}); | 3623 | 3.84k | return dist; | 3624 | 3.84k | } | 3625 | 22.3k | else { | 3626 | 22.3k | fn::impl(i, n); | 3627 | 22.3k | return n; | 3628 | 22.3k | } | 3629 | 26.2k | } |
Unexecuted instantiation: std::__1::enable_if<sized_sentinel_for<wchar_t const*, wchar_t const*>, nano::ranges::incrementable_traits<wchar_t const*>::difference_type>::type nano::ranges::detail::advance_::fn::impl<wchar_t const*, wchar_t const*>(wchar_t const*&, nano::ranges::incrementable_traits<wchar_t const*>::difference_type, wchar_t const*) |
3630 | | |
3631 | | template <typename I, typename S> |
3632 | | static constexpr auto impl(I& i, iter_difference_t<I> n, S bound) |
3633 | | -> std::enable_if_t<bidirectional_iterator<I> && |
3634 | | !sized_sentinel_for<S, I>, |
3635 | | iter_difference_t<I>> |
3636 | 5.20k | { |
3637 | 5.20k | constexpr iter_difference_t<I> zero{0}; |
3638 | 5.20k | iter_difference_t<I> counter{0}; |
3639 | | |
3640 | 5.20k | if (n < zero) { |
3641 | 0 | do { |
3642 | 0 | --i; |
3643 | 0 | --counter; // Yes, really |
3644 | 0 | } while (++n < zero && i != bound); |
3645 | 0 | } |
3646 | 5.20k | else { |
3647 | 17.3k | while (n-- > zero && i != bound) { |
3648 | 12.1k | ++i; |
3649 | 12.1k | ++counter; |
3650 | 12.1k | } |
3651 | 5.20k | } |
3652 | | |
3653 | 5.20k | return counter; |
3654 | 5.20k | } std::__1::enable_if<(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(!(sized_sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) Line | Count | Source | 3636 | 5.20k | { | 3637 | 5.20k | constexpr iter_difference_t<I> zero{0}; | 3638 | 5.20k | iter_difference_t<I> counter{0}; | 3639 | | | 3640 | 5.20k | if (n < zero) { | 3641 | 0 | do { | 3642 | 0 | --i; | 3643 | 0 | --counter; // Yes, really | 3644 | 0 | } while (++n < zero && i != bound); | 3645 | 0 | } | 3646 | 5.20k | else { | 3647 | 17.3k | while (n-- > zero && i != bound) { | 3648 | 12.1k | ++i; | 3649 | 12.1k | ++counter; | 3650 | 12.1k | } | 3651 | 5.20k | } | 3652 | | | 3653 | 5.20k | return counter; | 3654 | 5.20k | } |
Unexecuted instantiation: std::__1::enable_if<(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(!(sized_sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) |
3655 | | |
3656 | | template <typename I, typename S> |
3657 | | static constexpr auto impl(I& i, iter_difference_t<I> n, S bound) |
3658 | | -> std::enable_if_t<!bidirectional_iterator<I> && |
3659 | | !sized_sentinel_for<S, I>, |
3660 | | iter_difference_t<I>> |
3661 | 3.47k | { |
3662 | 3.47k | constexpr iter_difference_t<I> zero{0}; |
3663 | 3.47k | iter_difference_t<I> counter{0}; |
3664 | | |
3665 | 17.3k | while (n-- > zero && i != bound) { |
3666 | 13.8k | ++i; |
3667 | 13.8k | ++counter; |
3668 | 13.8k | } |
3669 | | |
3670 | 3.47k | return counter; |
3671 | 3.47k | } std::__1::enable_if<(!(bidirectional_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>))&&(!(sized_sentinel_for<nano::ranges::default_sentinel_t, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>)), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type, nano::ranges::default_sentinel_t) Line | Count | Source | 3661 | 3.47k | { | 3662 | 3.47k | constexpr iter_difference_t<I> zero{0}; | 3663 | 3.47k | iter_difference_t<I> counter{0}; | 3664 | | | 3665 | 17.3k | while (n-- > zero && i != bound) { | 3666 | 13.8k | ++i; | 3667 | 13.8k | ++counter; | 3668 | 13.8k | } | 3669 | | | 3670 | 3.47k | return counter; | 3671 | 3.47k | } |
Unexecuted instantiation: std::__1::enable_if<(!(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >))&&(!(sized_sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >)), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) Unexecuted instantiation: std::__1::enable_if<(!(bidirectional_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>))&&(!(sized_sentinel_for<nano::ranges::default_sentinel_t, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>)), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type, nano::ranges::default_sentinel_t) Unexecuted instantiation: std::__1::enable_if<(!(bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >))&&(!(sized_sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >)), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::advance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) |
3672 | | |
3673 | | public: |
3674 | | template <typename I> |
3675 | | constexpr auto operator()(I& i, iter_difference_t<I> n) const |
3676 | | -> std::enable_if_t<input_or_output_iterator<I>> |
3677 | 42.1M | { |
3678 | 42.1M | fn::impl(i, n); |
3679 | 42.1M | } std::__1::enable_if<input_or_output_iterator<char const*>, void>::type nano::ranges::detail::advance_::fn::operator()<char const*>(char const*&, nano::ranges::incrementable_traits<char const*>::difference_type) const Line | Count | Source | 3677 | 20.3M | { | 3678 | 20.3M | fn::impl(i, n); | 3679 | 20.3M | } |
std::__1::enable_if<input_or_output_iterator<wchar_t const*>, void>::type nano::ranges::detail::advance_::fn::operator()<wchar_t const*>(wchar_t const*&, nano::ranges::incrementable_traits<wchar_t const*>::difference_type) const Line | Count | Source | 3677 | 21.7M | { | 3678 | 21.7M | fn::impl(i, n); | 3679 | 21.7M | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type) const std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type) const Line | Count | Source | 3677 | 834 | { | 3678 | 834 | fn::impl(i, n); | 3679 | 834 | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >, void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) const std::__1::enable_if<input_or_output_iterator<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >, void>::type nano::ranges::detail::advance_::fn::operator()<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >(std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>&, nano::ranges::incrementable_traits<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >::difference_type) const Line | Count | Source | 3677 | 1.41k | { | 3678 | 1.41k | fn::impl(i, n); | 3679 | 1.41k | } |
std::__1::enable_if<input_or_output_iterator<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >, void>::type nano::ranges::detail::advance_::fn::operator()<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >(std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>&, nano::ranges::incrementable_traits<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >::difference_type) const Line | Count | Source | 3677 | 33.5k | { | 3678 | 33.5k | fn::impl(i, n); | 3679 | 33.5k | } |
|
3680 | | |
3681 | | template <typename I, typename S> |
3682 | | constexpr auto operator()(I& i, S bound) const |
3683 | | -> std::enable_if_t<input_or_output_iterator<I> && |
3684 | | sentinel_for<S, I>> |
3685 | 3.21M | { |
3686 | 3.21M | fn::impl(i, bound, priority_tag<2>{}); |
3687 | 3.21M | } std::__1::enable_if<(input_or_output_iterator<char const*>)&&(sentinel_for<char const*, char const*>), void>::type nano::ranges::detail::advance_::fn::operator()<char const*, char const*>(char const*&, char const*) const Line | Count | Source | 3685 | 1.67M | { | 3686 | 1.67M | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 1.67M | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >), void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Line | Count | Source | 3685 | 20.9k | { | 3686 | 20.9k | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 20.9k | } |
std::__1::enable_if<(input_or_output_iterator<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >)&&(sentinel_for<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >), void>::type nano::ranges::detail::advance_::fn::operator()<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>&, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>) const Line | Count | Source | 3685 | 6.99k | { | 3686 | 6.99k | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 6.99k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const Line | Count | Source | 3685 | 1.40k | { | 3686 | 1.40k | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 1.40k | } |
std::__1::enable_if<(input_or_output_iterator<wchar_t const*>)&&(sentinel_for<wchar_t const*, wchar_t const*>), void>::type nano::ranges::detail::advance_::fn::operator()<wchar_t const*, wchar_t const*>(wchar_t const*&, wchar_t const*) const Line | Count | Source | 3685 | 1.48M | { | 3686 | 1.48M | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 1.48M | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >), void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Line | Count | Source | 3685 | 20.4k | { | 3686 | 20.4k | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 20.4k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), void>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const Line | Count | Source | 3685 | 4.62k | { | 3686 | 4.62k | fn::impl(i, bound, priority_tag<2>{}); | 3687 | 4.62k | } |
|
3688 | | |
3689 | | template <typename I, typename S> |
3690 | | constexpr auto operator()(I& i, |
3691 | | iter_difference_t<I> n, |
3692 | | S bound) const |
3693 | | -> std::enable_if_t<input_or_output_iterator<I> && |
3694 | | sentinel_for<S, I>, |
3695 | | iter_difference_t<I>> |
3696 | 34.8k | { |
3697 | 34.8k | return n - fn::impl(i, n, bound); |
3698 | 34.8k | } std::__1::enable_if<(input_or_output_iterator<char const*>)&&(sentinel_for<char const*, char const*>), nano::ranges::incrementable_traits<char const*>::difference_type>::type nano::ranges::detail::advance_::fn::operator()<char const*, char const*>(char const*&, nano::ranges::incrementable_traits<char const*>::difference_type, char const*) const Line | Count | Source | 3696 | 26.2k | { | 3697 | 26.2k | return n - fn::impl(i, n, bound); | 3698 | 26.2k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>)&&(sentinel_for<nano::ranges::default_sentinel_t, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type, nano::ranges::default_sentinel_t) const Line | Count | Source | 3696 | 3.47k | { | 3697 | 3.47k | return n - fn::impl(i, n, bound); | 3698 | 3.47k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Line | Count | Source | 3696 | 5.20k | { | 3697 | 5.20k | return n - fn::impl(i, n, bound); | 3698 | 5.20k | } |
Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<wchar_t const*>)&&(sentinel_for<wchar_t const*, wchar_t const*>), nano::ranges::incrementable_traits<wchar_t const*>::difference_type>::type nano::ranges::detail::advance_::fn::operator()<wchar_t const*, wchar_t const*>(wchar_t const*&, nano::ranges::incrementable_traits<wchar_t const*>::difference_type, wchar_t const*) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>)&&(sentinel_for<nano::ranges::default_sentinel_t, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type, nano::ranges::default_sentinel_t) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::advance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const |
3699 | | }; |
3700 | | |
3701 | | } // namespace advance_ |
3702 | | } // namespace detail |
3703 | | |
3704 | | NANO_INLINE_VAR(detail::advance_::fn, advance) |
3705 | | |
3706 | | namespace detail { |
3707 | | namespace distance_ { |
3708 | | |
3709 | | struct fn { |
3710 | | private: |
3711 | | template <typename I, typename S> |
3712 | | static constexpr auto impl(I i, S s) |
3713 | | -> std::enable_if_t<sized_sentinel_for<S, I>, |
3714 | | iter_difference_t<I>> |
3715 | 29.3M | { |
3716 | 29.3M | return s - i; |
3717 | 29.3M | } Unexecuted instantiation: std::__1::enable_if<sized_sentinel_for<std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*> >, nano::ranges::incrementable_traits<std::__1::__wrap_iter<char*> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*> >(std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*>) std::__1::enable_if<sized_sentinel_for<char const*, char const*>, nano::ranges::incrementable_traits<char const*>::difference_type>::type nano::ranges::detail::distance_::fn::impl<char const*, char const*>(char const*, char const*) Line | Count | Source | 3715 | 19.7M | { | 3716 | 19.7M | return s - i; | 3717 | 19.7M | } |
std::__1::enable_if<sized_sentinel_for<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >, nano::ranges::incrementable_traits<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>) Line | Count | Source | 3715 | 28.8k | { | 3716 | 28.8k | return s - i; | 3717 | 28.8k | } |
Unexecuted instantiation: std::__1::enable_if<sized_sentinel_for<std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*> >, nano::ranges::incrementable_traits<std::__1::__wrap_iter<wchar_t*> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*>) std::__1::enable_if<sized_sentinel_for<wchar_t const*, wchar_t const*>, nano::ranges::incrementable_traits<wchar_t const*>::difference_type>::type nano::ranges::detail::distance_::fn::impl<wchar_t const*, wchar_t const*>(wchar_t const*, wchar_t const*) Line | Count | Source | 3715 | 9.61M | { | 3716 | 9.61M | return s - i; | 3717 | 9.61M | } |
|
3718 | | |
3719 | | template <typename I, typename S> |
3720 | | static constexpr auto impl(I i, S s) |
3721 | | -> std::enable_if_t<!sized_sentinel_for<S, I>, |
3722 | | iter_difference_t<I>> |
3723 | 0 | { |
3724 | 0 | iter_difference_t<I> counter{0}; |
3725 | 0 | while (i != s) { |
3726 | 0 | ++i; |
3727 | 0 | ++counter; |
3728 | 0 | } |
3729 | 0 | return counter; |
3730 | 0 | } Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator) Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>) Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>) Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>) Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator) Unexecuted instantiation: std::__1::enable_if<!(sized_sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::distance_::fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>) |
3731 | | |
3732 | | template <typename R> |
3733 | | static constexpr auto impl(R&& r) |
3734 | | -> std::enable_if_t<sized_range<R>, |
3735 | | iter_difference_t<iterator_t<R>>> |
3736 | | { |
3737 | | return static_cast<iter_difference_t<iterator_t<R>>>( |
3738 | | ranges::size(r)); |
3739 | | } |
3740 | | |
3741 | | template <typename R> |
3742 | | static constexpr auto impl(R&& r) |
3743 | | -> std::enable_if_t<!sized_range<R>, |
3744 | | iter_difference_t<iterator_t<R>>> |
3745 | | { |
3746 | | return fn::impl(ranges::begin(r), ranges::end(r)); |
3747 | | } |
3748 | | |
3749 | | public: |
3750 | | template <typename I, typename S> |
3751 | | constexpr auto operator()(I first, S last) const |
3752 | | -> std::enable_if_t<input_or_output_iterator<I> && |
3753 | | sentinel_for<S, I>, |
3754 | | iter_difference_t<I>> |
3755 | 29.3M | { |
3756 | 29.3M | return fn::impl(std::move(first), std::move(last)); |
3757 | 29.3M | } Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<std::__1::__wrap_iter<char*> >)&&(sentinel_for<std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*> >), nano::ranges::incrementable_traits<std::__1::__wrap_iter<char*> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*> >(std::__1::__wrap_iter<char*>, std::__1::__wrap_iter<char*>) const std::__1::enable_if<(input_or_output_iterator<char const*>)&&(sentinel_for<char const*, char const*>), nano::ranges::incrementable_traits<char const*>::difference_type>::type nano::ranges::detail::distance_::fn::operator()<char const*, char const*>(char const*, char const*) const Line | Count | Source | 3755 | 19.7M | { | 3756 | 19.7M | return fn::impl(std::move(first), std::move(last)); | 3757 | 19.7M | } |
Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>)&&(sentinel_for<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>) const std::__1::enable_if<(input_or_output_iterator<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >)&&(sentinel_for<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >), nano::ranges::incrementable_traits<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>) const Line | Count | Source | 3755 | 28.8k | { | 3756 | 28.8k | return fn::impl(std::move(first), std::move(last)); | 3757 | 28.8k | } |
Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<std::__1::__wrap_iter<wchar_t*> >)&&(sentinel_for<std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*> >), nano::ranges::incrementable_traits<std::__1::__wrap_iter<wchar_t*> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>, std::__1::__wrap_iter<wchar_t*>) const std::__1::enable_if<(input_or_output_iterator<wchar_t const*>)&&(sentinel_for<wchar_t const*, wchar_t const*>), nano::ranges::incrementable_traits<wchar_t const*>::difference_type>::type nano::ranges::detail::distance_::fn::operator()<wchar_t const*, wchar_t const*>(wchar_t const*, wchar_t const*) const Line | Count | Source | 3755 | 9.61M | { | 3756 | 9.61M | return fn::impl(std::move(first), std::move(last)); | 3757 | 9.61M | } |
Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>)&&(sentinel_for<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>), nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator) const Unexecuted instantiation: std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type>::type nano::ranges::detail::distance_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>) const |
3758 | | |
3759 | | template <typename R> |
3760 | | constexpr auto operator()(R&& r) const |
3761 | | -> std::enable_if_t<range<R>, iter_difference_t<iterator_t<R>>> |
3762 | | { |
3763 | | return fn::impl(std::forward<R>(r)); |
3764 | | } |
3765 | | }; |
3766 | | |
3767 | | } // namespace distance_ |
3768 | | } // namespace detail |
3769 | | |
3770 | | NANO_INLINE_VAR(detail::distance_::fn, distance) |
3771 | | |
3772 | | namespace detail { |
3773 | | namespace next_ { |
3774 | | |
3775 | | struct fn { |
3776 | | template <typename I> |
3777 | | constexpr auto operator()(I x) const |
3778 | | -> std::enable_if_t<input_or_output_iterator<I>, I> |
3779 | 21.2M | { |
3780 | 21.2M | ++x; |
3781 | 21.2M | return x; |
3782 | 21.2M | } std::__1::enable_if<input_or_output_iterator<char const*>, char const*>::type nano::ranges::detail::next_::fn::operator()<char const*>(char const*) const Line | Count | Source | 3779 | 8.72M | { | 3780 | 8.72M | ++x; | 3781 | 8.72M | return x; | 3782 | 8.72M | } |
std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::type nano::ranges::detail::next_::fn::operator()<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator) const Line | Count | Source | 3779 | 408k | { | 3780 | 408k | ++x; | 3781 | 408k | return x; | 3782 | 408k | } |
std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>) const Line | Count | Source | 3779 | 2.67k | { | 3780 | 2.67k | ++x; | 3781 | 2.67k | return x; | 3782 | 2.67k | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>) const std::__1::enable_if<input_or_output_iterator<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::next_::fn::operator()<wchar_t const*>(wchar_t const*) const Line | Count | Source | 3779 | 11.3M | { | 3780 | 11.3M | ++x; | 3781 | 11.3M | return x; | 3782 | 11.3M | } |
std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>) const Line | Count | Source | 3779 | 2.20k | { | 3780 | 2.20k | ++x; | 3781 | 2.20k | return x; | 3782 | 2.20k | } |
std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::type nano::ranges::detail::next_::fn::operator()<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator) const Line | Count | Source | 3779 | 721k | { | 3780 | 721k | ++x; | 3781 | 721k | return x; | 3782 | 721k | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>) const |
3783 | | |
3784 | | template <typename I> |
3785 | | constexpr auto operator()(I x, iter_difference_t<I> n) const |
3786 | | -> std::enable_if_t<input_or_output_iterator<I>, I> |
3787 | 42.1M | { |
3788 | 42.1M | ranges::advance(x, n); |
3789 | 42.1M | return x; |
3790 | 42.1M | } std::__1::enable_if<input_or_output_iterator<char const*>, char const*>::type nano::ranges::detail::next_::fn::operator()<char const*>(char const*, nano::ranges::incrementable_traits<char const*>::difference_type) const Line | Count | Source | 3787 | 20.3M | { | 3788 | 20.3M | ranges::advance(x, n); | 3789 | 20.3M | return x; | 3790 | 20.3M | } |
std::__1::enable_if<input_or_output_iterator<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::next_::fn::operator()<wchar_t const*>(wchar_t const*, nano::ranges::incrementable_traits<wchar_t const*>::difference_type) const Line | Count | Source | 3787 | 21.7M | { | 3788 | 21.7M | ranges::advance(x, n); | 3789 | 21.7M | return x; | 3790 | 21.7M | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>, scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::type nano::ranges::detail::next_::fn::operator()<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<char>::forward_iterator>::difference_type) const std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::difference_type) const Line | Count | Source | 3787 | 834 | { | 3788 | 834 | ranges::advance(x, n); | 3789 | 834 | return x; | 3790 | 834 | } |
Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::type nano::ranges::detail::next_::fn::operator()<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::incrementable_traits<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator>::difference_type) const Unexecuted instantiation: std::__1::enable_if<input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, nano::ranges::incrementable_traits<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::difference_type) const std::__1::enable_if<input_or_output_iterator<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >::type nano::ranges::detail::next_::fn::operator()<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >(std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, nano::ranges::incrementable_traits<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l> >::difference_type) const Line | Count | Source | 3787 | 1.41k | { | 3788 | 1.41k | ranges::advance(x, n); | 3789 | 1.41k | return x; | 3790 | 1.41k | } |
std::__1::enable_if<input_or_output_iterator<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >::type nano::ranges::detail::next_::fn::operator()<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >(std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, nano::ranges::incrementable_traits<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l> >::difference_type) const Line | Count | Source | 3787 | 33.5k | { | 3788 | 33.5k | ranges::advance(x, n); | 3789 | 33.5k | return x; | 3790 | 33.5k | } |
|
3791 | | |
3792 | | template <typename I, typename S> |
3793 | | constexpr auto operator()(I x, S bound) const |
3794 | | -> std::enable_if_t<input_or_output_iterator<I> && |
3795 | | sentinel_for<S, I>, |
3796 | | I> |
3797 | 3.21M | { |
3798 | 3.21M | ranges::advance(x, bound); |
3799 | 3.21M | return x; |
3800 | 3.21M | } std::__1::enable_if<(input_or_output_iterator<char const*>)&&(sentinel_for<char const*, char const*>), char const*>::type nano::ranges::detail::next_::fn::operator()<char const*, char const*>(char const*, char const*) const Line | Count | Source | 3797 | 1.67M | { | 3798 | 1.67M | ranges::advance(x, bound); | 3799 | 1.67M | return x; | 3800 | 1.67M | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >), scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Line | Count | Source | 3797 | 20.9k | { | 3798 | 20.9k | ranges::advance(x, bound); | 3799 | 20.9k | return x; | 3800 | 20.9k | } |
std::__1::enable_if<(input_or_output_iterator<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >)&&(sentinel_for<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >), std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >::type nano::ranges::detail::next_::fn::operator()<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*> >(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t>*>) const Line | Count | Source | 3797 | 6.99k | { | 3798 | 6.99k | ranges::advance(x, bound); | 3799 | 6.99k | return x; | 3800 | 6.99k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >), scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const Line | Count | Source | 3797 | 1.40k | { | 3798 | 1.40k | ranges::advance(x, bound); | 3799 | 1.40k | return x; | 3800 | 1.40k | } |
std::__1::enable_if<(input_or_output_iterator<wchar_t const*>)&&(sentinel_for<wchar_t const*, wchar_t const*>), wchar_t const*>::type nano::ranges::detail::next_::fn::operator()<wchar_t const*, wchar_t const*>(wchar_t const*, wchar_t const*) const Line | Count | Source | 3797 | 1.48M | { | 3798 | 1.48M | ranges::advance(x, bound); | 3799 | 1.48M | return x; | 3800 | 1.48M | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >), scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) const Line | Count | Source | 3797 | 20.4k | { | 3798 | 20.4k | ranges::advance(x, bound); | 3799 | 20.4k | return x; | 3800 | 20.4k | } |
std::__1::enable_if<(input_or_output_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >)&&(sentinel_for<scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >), scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> >::type nano::ranges::detail::next_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) const Line | Count | Source | 3797 | 4.62k | { | 3798 | 4.62k | ranges::advance(x, bound); | 3799 | 4.62k | return x; | 3800 | 4.62k | } |
|
3801 | | |
3802 | | template <typename I, typename S> |
3803 | | constexpr auto operator()(I x, |
3804 | | iter_difference_t<I> n, |
3805 | | S bound) const |
3806 | | -> std::enable_if_t<input_or_output_iterator<I> && |
3807 | | sentinel_for<S, I>, |
3808 | | I> |
3809 | | { |
3810 | | ranges::advance(x, n, bound); |
3811 | | return x; |
3812 | | } |
3813 | | }; |
3814 | | |
3815 | | } // namespace next_ |
3816 | | } // namespace detail |
3817 | | |
3818 | | NANO_INLINE_VAR(detail::next_::fn, next) |
3819 | | |
3820 | | namespace detail { |
3821 | | namespace prev_ { |
3822 | | |
3823 | | struct fn { |
3824 | | template <typename I> |
3825 | | constexpr auto operator()(I x) const |
3826 | | -> std::enable_if_t<bidirectional_iterator<I>, I> |
3827 | 982k | { |
3828 | 982k | --x; |
3829 | 982k | return x; |
3830 | 982k | } std::__1::enable_if<bidirectional_iterator<char const*>, char const*>::type nano::ranges::detail::prev_::fn::operator()<char const*>(char const*) const Line | Count | Source | 3827 | 540k | { | 3828 | 540k | --x; | 3829 | 540k | return x; | 3830 | 540k | } |
Unexecuted instantiation: std::__1::enable_if<bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >::type nano::ranges::detail::prev_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>) const std::__1::enable_if<bidirectional_iterator<wchar_t const*>, wchar_t const*>::type nano::ranges::detail::prev_::fn::operator()<wchar_t const*>(wchar_t const*) const Line | Count | Source | 3827 | 442k | { | 3828 | 442k | --x; | 3829 | 442k | return x; | 3830 | 442k | } |
Unexecuted instantiation: std::__1::enable_if<bidirectional_iterator<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >::type nano::ranges::detail::prev_::fn::operator()<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> >(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>) const |
3831 | | |
3832 | | template <typename I> |
3833 | | constexpr auto operator()(I x, iter_difference_t<I> n) const |
3834 | | -> std::enable_if_t<bidirectional_iterator<I>, I> |
3835 | | { |
3836 | | ranges::advance(x, -n); |
3837 | | return x; |
3838 | | } |
3839 | | |
3840 | | template <typename I, typename S> |
3841 | | constexpr auto operator()(I x, |
3842 | | iter_difference_t<I> n, |
3843 | | S bound) const -> std:: |
3844 | | enable_if_t<bidirectional_iterator<I> && sentinel_for<S, I>, I> |
3845 | | { |
3846 | | ranges::advance(x, -n, bound); |
3847 | | return x; |
3848 | | } |
3849 | | }; |
3850 | | |
3851 | | } // namespace prev_ |
3852 | | } // namespace detail |
3853 | | |
3854 | | NANO_INLINE_VAR(detail::prev_::fn, prev) |
3855 | | |
3856 | | NANO_END_NAMESPACE |
3857 | | |
3858 | | #endif |
3859 | | |
3860 | | NANO_BEGIN_NAMESPACE |
3861 | | |
3862 | | namespace reverse_iterator_ { |
3863 | | |
3864 | | template <typename I> |
3865 | | class reverse_iterator { |
3866 | | static_assert(bidirectional_iterator<I>, |
3867 | | "Template argument to reverse_iterator must model " |
3868 | | "BidirectionalIterator"); |
3869 | | |
3870 | | public: |
3871 | | using iterator_type = I; |
3872 | | using difference_type = iter_difference_t<I>; |
3873 | | using value_type = iter_value_t<I>; |
3874 | | using iterator_category = detail::legacy_iterator_category_t<I>; |
3875 | | using reference = iter_reference_t<I>; |
3876 | | using pointer = I; |
3877 | | |
3878 | | constexpr reverse_iterator() = default; |
3879 | | |
3880 | 0 | explicit constexpr reverse_iterator(I x) : current_(std::move(x)) {} |
3881 | | |
3882 | | template <typename U, std::enable_if_t<convertible_to<U, I>, int> = 0> |
3883 | | |
3884 | | constexpr reverse_iterator(const reverse_iterator<U>& i) |
3885 | | : current_(i.base()) |
3886 | | { |
3887 | | } |
3888 | | |
3889 | | template <typename U, std::enable_if_t<convertible_to<U, I>, int> = 0> |
3890 | | |
3891 | | constexpr reverse_iterator& operator=(const reverse_iterator<U>& i) |
3892 | | { |
3893 | | current_ = i.base(); |
3894 | | return *this; |
3895 | | } |
3896 | | |
3897 | | constexpr I base() const |
3898 | 0 | { |
3899 | 0 | return current_; |
3900 | 0 | } |
3901 | | |
3902 | | constexpr reference operator*() const |
3903 | 0 | { |
3904 | 0 | return *prev(current_); |
3905 | 0 | } |
3906 | | |
3907 | | constexpr pointer operator->() const |
3908 | | { |
3909 | | return prev(current_); |
3910 | | } |
3911 | | |
3912 | | constexpr reverse_iterator& operator++() |
3913 | 0 | { |
3914 | 0 | --current_; |
3915 | 0 | return *this; |
3916 | 0 | } |
3917 | | |
3918 | | constexpr reverse_iterator operator++(int) |
3919 | | { |
3920 | | reverse_iterator tmp = *this; |
3921 | | --current_; |
3922 | | return tmp; |
3923 | | } |
3924 | | |
3925 | | constexpr reverse_iterator& operator--() |
3926 | | { |
3927 | | ++current_; |
3928 | | return *this; |
3929 | | } |
3930 | | |
3931 | | constexpr reverse_iterator operator--(int) |
3932 | | { |
3933 | | reverse_iterator tmp = *this; |
3934 | | ++current_; |
3935 | | return tmp; |
3936 | | } |
3937 | | |
3938 | | template <typename II = I> |
3939 | | constexpr std::enable_if_t<random_access_iterator<II>, reverse_iterator> |
3940 | | operator+(difference_type n) const |
3941 | | { |
3942 | | return reverse_iterator(current_ - n); |
3943 | | } |
3944 | | |
3945 | | template <typename II = I> |
3946 | | constexpr std::enable_if_t<random_access_iterator<II>, |
3947 | | reverse_iterator&> |
3948 | | operator+=(difference_type n) |
3949 | | { |
3950 | | current_ -= n; |
3951 | | return *this; |
3952 | | } |
3953 | | |
3954 | | template <typename II = I> |
3955 | | constexpr std::enable_if_t<random_access_iterator<II>, reverse_iterator> |
3956 | | operator-(difference_type n) const |
3957 | | { |
3958 | | return reverse_iterator(current_ + n); |
3959 | | } |
3960 | | |
3961 | | template <typename II = I> |
3962 | | constexpr std::enable_if_t<random_access_iterator<II>, |
3963 | | reverse_iterator&> |
3964 | | operator-=(difference_type n) |
3965 | | { |
3966 | | current_ += n; |
3967 | | return *this; |
3968 | | } |
3969 | | |
3970 | | template <typename II = I> |
3971 | | constexpr std::enable_if_t<random_access_iterator<II>, reference> |
3972 | | operator[](difference_type n) const |
3973 | | { |
3974 | | return current_[-n - 1]; |
3975 | | } |
3976 | | |
3977 | | friend constexpr iter_rvalue_reference_t<I> |
3978 | | iter_move(const reverse_iterator& i) noexcept( |
3979 | | noexcept(ranges::iter_move(std::declval<I&>())) && noexcept( |
3980 | | --std::declval<I&>()) && |
3981 | | std::is_nothrow_copy_constructible<I>::value) |
3982 | | { |
3983 | | return ranges::iter_move(prev(i.current_)); |
3984 | | } |
3985 | | |
3986 | | template <typename I2> |
3987 | | friend constexpr auto iter_swap( |
3988 | | const reverse_iterator& x, |
3989 | | const reverse_iterator<I2>& |
3990 | | y) noexcept(noexcept(ranges:: |
3991 | | iter_swap( |
3992 | | std::declval<I>(), |
3993 | | std::declval< |
3994 | | I>())) && noexcept(--std:: |
3995 | | declval< |
3996 | | I&>())) |
3997 | | -> std::enable_if_t<indirectly_swappable<I2, I>> |
3998 | | |
3999 | | { |
4000 | | ranges::iter_swap(prev(x.current_), prev(y.base())); |
4001 | | } |
4002 | | |
4003 | | private: |
4004 | | I current_{}; |
4005 | | }; |
4006 | | |
4007 | | template <typename I1, typename I2> |
4008 | | constexpr std::enable_if_t<equality_comparable_with<I1, I2>, bool> |
4009 | | operator==(const reverse_iterator<I1>& x, const reverse_iterator<I2>& y) |
4010 | | { |
4011 | | return x.base() == y.base(); |
4012 | | } |
4013 | | |
4014 | | template <typename I1, typename I2> |
4015 | | constexpr std::enable_if_t<equality_comparable_with<I1, I2>, bool> |
4016 | | operator!=(const reverse_iterator<I1>& x, const reverse_iterator<I2>& y) |
4017 | 0 | { |
4018 | 0 | return x.base() != y.base(); |
4019 | 0 | } |
4020 | | |
4021 | | template <typename I1, typename I2> |
4022 | | constexpr std::enable_if_t<totally_ordered_with<I1, I2>, bool> operator<( |
4023 | | const reverse_iterator<I1>& x, |
4024 | | const reverse_iterator<I2>& y) |
4025 | | { |
4026 | | return x.base() > y.base(); |
4027 | | } |
4028 | | |
4029 | | template <typename I1, typename I2> |
4030 | | constexpr std::enable_if_t<totally_ordered_with<I1, I2>, bool> operator>( |
4031 | | const reverse_iterator<I1>& x, |
4032 | | const reverse_iterator<I2>& y) |
4033 | | { |
4034 | | return x.base() < y.base(); |
4035 | | } |
4036 | | |
4037 | | template <typename I1, typename I2> |
4038 | | constexpr std::enable_if_t<totally_ordered_with<I1, I2>, bool> operator>=( |
4039 | | const reverse_iterator<I1>& x, |
4040 | | const reverse_iterator<I2>& y) |
4041 | | { |
4042 | | return x.base() <= y.base(); |
4043 | | } |
4044 | | |
4045 | | template <typename I1, typename I2> |
4046 | | constexpr std::enable_if_t<totally_ordered_with<I1, I2>, bool> operator<=( |
4047 | | const reverse_iterator<I1>& x, |
4048 | | const reverse_iterator<I2>& y) |
4049 | | { |
4050 | | return x.base() >= y.base(); |
4051 | | } |
4052 | | |
4053 | | template <typename I1, typename I2> |
4054 | | constexpr std::enable_if_t<sized_sentinel_for<I1, I2>, |
4055 | | iter_difference_t<I2>> |
4056 | | operator-(const reverse_iterator<I1>& x, const reverse_iterator<I2>& y) |
4057 | | { |
4058 | | return y.base() - x.base(); |
4059 | | } |
4060 | | |
4061 | | template <typename I> |
4062 | | constexpr std::enable_if_t<random_access_iterator<I>, reverse_iterator<I>> |
4063 | | operator+(iter_difference_t<I> n, const reverse_iterator<I>& x) |
4064 | | { |
4065 | | return reverse_iterator<I>(x.base() - n); |
4066 | | } |
4067 | | |
4068 | | } // namespace reverse_iterator_ |
4069 | | |
4070 | | using reverse_iterator_::reverse_iterator; |
4071 | | |
4072 | | template <typename I> |
4073 | | constexpr std::enable_if_t<bidirectional_iterator<I>, reverse_iterator<I>> |
4074 | | make_reverse_iterator(I i) |
4075 | 0 | { |
4076 | 0 | return reverse_iterator<I>(std::move(i)); |
4077 | 0 | } |
4078 | | |
4079 | | NANO_END_NAMESPACE |
4080 | | |
4081 | | #endif |
4082 | | |
4083 | | NANO_BEGIN_NAMESPACE |
4084 | | |
4085 | | namespace detail { |
4086 | | namespace rbegin_ { |
4087 | | |
4088 | | template <typename T> |
4089 | | void rbegin(T&) = delete; |
4090 | | |
4091 | | template <typename T> |
4092 | | void rbegin(const T&) = delete; |
4093 | | |
4094 | | struct fn { |
4095 | | private: |
4096 | | template <typename T, |
4097 | | std::enable_if_t< |
4098 | | !std::is_lvalue_reference_v<T> && |
4099 | | !enable_borrowed_range<std::remove_cv_t<T>>, |
4100 | | int> = 0> |
4101 | | static constexpr void impl(T&&, priority_tag<3>) = delete; |
4102 | | |
4103 | | template < |
4104 | | typename T, |
4105 | | typename I = decltype(decay_copy(std::declval<T>().rbegin()))> |
4106 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
4107 | | noexcept(decay_copy(std::forward<T>(t).rbegin()))) |
4108 | | -> std::enable_if_t<input_or_output_iterator<I>, I> |
4109 | | { |
4110 | | return std::forward<T>(t).rbegin(); |
4111 | | } |
4112 | | |
4113 | | template < |
4114 | | typename T, |
4115 | | typename I = decltype(decay_copy(rbegin(std::declval<T>())))> |
4116 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
4117 | | noexcept(decay_copy(rbegin(std::forward<T>(t))))) |
4118 | | -> std::enable_if_t<input_or_output_iterator<I>, I> |
4119 | | { |
4120 | | return rbegin(std::forward<T>(t)); |
4121 | | } |
4122 | | |
4123 | | template <typename T, |
4124 | | typename I = decltype(ranges::begin(std::declval<T>())), |
4125 | | typename S = decltype(ranges::end(std::declval<T>()))> |
4126 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
4127 | | noexcept(ranges::make_reverse_iterator( |
4128 | | ranges::end(std::forward<T>(t))))) |
4129 | | -> std::enable_if_t<same_as<I, S> && bidirectional_iterator<I>, |
4130 | | decltype(ranges::make_reverse_iterator( |
4131 | | ranges::end(std::forward<T>(t))))> |
4132 | | { |
4133 | | return ranges::make_reverse_iterator( |
4134 | | ranges::end(std::forward<T>(t))); |
4135 | | } |
4136 | | |
4137 | | public: |
4138 | | template <typename T> |
4139 | | constexpr auto operator()(T&& t) const |
4140 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
4141 | | priority_tag<3>{}))) |
4142 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<3>{})) |
4143 | | { |
4144 | | return fn::impl(std::forward<T>(t), priority_tag<3>{}); |
4145 | | } |
4146 | | }; |
4147 | | |
4148 | | } // namespace rbegin_ |
4149 | | } // namespace detail |
4150 | | |
4151 | | NANO_INLINE_VAR(detail::rbegin_::fn, rbegin) |
4152 | | |
4153 | | namespace detail { |
4154 | | namespace rend_ { |
4155 | | |
4156 | | template <typename T> |
4157 | | void rend(T&) = delete; |
4158 | | |
4159 | | template <typename T> |
4160 | | void rend(const T&) = delete; |
4161 | | |
4162 | | struct fn { |
4163 | | private: |
4164 | | template <typename T, |
4165 | | std::enable_if_t< |
4166 | | !std::is_lvalue_reference_v<T> && |
4167 | | !enable_borrowed_range<std::remove_cv_t<T>>, |
4168 | | int> = 0> |
4169 | | static constexpr void impl(T&&, priority_tag<3>) = delete; |
4170 | | |
4171 | | template < |
4172 | | typename T, |
4173 | | typename I = decltype(ranges::rbegin(std::declval<T>())), |
4174 | | typename S = decltype(decay_copy(std::declval<T>().rend()))> |
4175 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
4176 | | noexcept(decay_copy(std::forward<T>(t).rend()))) |
4177 | | -> std::enable_if_t<sentinel_for<S, I>, S> |
4178 | | { |
4179 | | return std::forward<T>(t).rend(); |
4180 | | } |
4181 | | |
4182 | | template < |
4183 | | typename T, |
4184 | | typename I = decltype(ranges::rbegin(std::declval<T>())), |
4185 | | typename S = decltype(decay_copy(rend(std::declval<T>())))> |
4186 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept( |
4187 | | noexcept(decay_copy(rend(std::forward<T>(t))))) |
4188 | | -> std::enable_if_t<sentinel_for<S, I>, S> |
4189 | | { |
4190 | | return rend(std::forward<T>(t)); |
4191 | | } |
4192 | | |
4193 | | template <typename T, |
4194 | | typename I = decltype(ranges::begin(std::declval<T>())), |
4195 | | typename S = decltype(ranges::end(std::declval<T>()))> |
4196 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
4197 | | noexcept(ranges::make_reverse_iterator( |
4198 | | ranges::begin(std::forward<T>(t))))) |
4199 | | -> std::enable_if_t<same_as<I, S> && bidirectional_iterator<I>, |
4200 | | decltype(ranges::make_reverse_iterator( |
4201 | | ranges::begin(std::forward<T>(t))))> |
4202 | | { |
4203 | | return ranges::make_reverse_iterator( |
4204 | | ranges::begin(std::forward<T>(t))); |
4205 | | } |
4206 | | |
4207 | | public: |
4208 | | template <typename T> |
4209 | | constexpr auto operator()(T&& t) const |
4210 | | noexcept(noexcept(fn::impl(std::forward<T>(t), |
4211 | | priority_tag<3>{}))) |
4212 | | -> decltype(fn::impl(std::forward<T>(t), priority_tag<3>{})) |
4213 | | { |
4214 | | return fn::impl(std::forward<T>(t), priority_tag<3>{}); |
4215 | | } |
4216 | | }; |
4217 | | |
4218 | | } // namespace rend_ |
4219 | | } // namespace detail |
4220 | | |
4221 | | NANO_INLINE_VAR(detail::rend_::fn, rend) |
4222 | | |
4223 | | namespace detail { |
4224 | | namespace crbegin_ { |
4225 | | |
4226 | | struct fn { |
4227 | | private: |
4228 | | template <typename T, |
4229 | | typename U = std::remove_reference_t<T>, |
4230 | | std::enable_if_t<std::is_lvalue_reference_v<T>, int> = 0> |
4231 | | static constexpr auto impl(T&& t) noexcept( |
4232 | | noexcept(ranges::rbegin(static_cast<const U&>(t)))) |
4233 | | -> decltype(ranges::rbegin(static_cast<const U&>(t))) |
4234 | | { |
4235 | | return ranges::rbegin(static_cast<const U&>(t)); |
4236 | | } |
4237 | | |
4238 | | template <typename T, |
4239 | | std::enable_if_t<!std::is_lvalue_reference_v<T>, int> = 0> |
4240 | | static constexpr auto impl(T&& t) noexcept( |
4241 | | noexcept(ranges::rbegin(static_cast<const T&&>(t)))) |
4242 | | -> decltype(ranges::rbegin(static_cast<const T&&>(t))) |
4243 | | { |
4244 | | return ranges::rbegin(static_cast<const T&&>(t)); |
4245 | | } |
4246 | | |
4247 | | public: |
4248 | | template <typename T> |
4249 | | constexpr auto operator()(T&& t) const |
4250 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
4251 | | -> decltype(fn::impl(std::forward<T>(t))) |
4252 | | { |
4253 | | return fn::impl(std::forward<T>(t)); |
4254 | | } |
4255 | | }; |
4256 | | |
4257 | | } // namespace crbegin_ |
4258 | | } // namespace detail |
4259 | | |
4260 | | NANO_INLINE_VAR(detail::crbegin_::fn, crbegin) |
4261 | | |
4262 | | namespace detail { |
4263 | | namespace crend_ { |
4264 | | |
4265 | | struct fn { |
4266 | | private: |
4267 | | template <typename T, |
4268 | | typename U = std::remove_reference_t<T>, |
4269 | | std::enable_if_t<std::is_lvalue_reference_v<T>, int> = 0> |
4270 | | static constexpr auto impl(T&& t) noexcept( |
4271 | | noexcept(ranges::rend(static_cast<const U&>(t)))) |
4272 | | -> decltype(ranges::rend(static_cast<const U&>(t))) |
4273 | | { |
4274 | | return ranges::rend(static_cast<const U&>(t)); |
4275 | | } |
4276 | | |
4277 | | template <typename T, |
4278 | | std::enable_if_t<!std::is_lvalue_reference_v<T>, int> = 0> |
4279 | | static constexpr auto impl(T&& t) noexcept( |
4280 | | noexcept(ranges::rend(static_cast<const T&&>(t)))) |
4281 | | -> decltype(ranges::rend(static_cast<const T&&>(t))) |
4282 | | { |
4283 | | return ranges::rend(static_cast<const T&&>(t)); |
4284 | | } |
4285 | | |
4286 | | public: |
4287 | | template <typename T> |
4288 | | constexpr auto operator()(T&& t) const |
4289 | | noexcept(noexcept(fn::impl(std::forward<T>(t)))) |
4290 | | -> decltype(fn::impl(std::forward<T>(t))) |
4291 | | { |
4292 | | return fn::impl(std::forward<T>(t)); |
4293 | | } |
4294 | | }; |
4295 | | |
4296 | | } // namespace crend_ |
4297 | | } // namespace detail |
4298 | | |
4299 | | NANO_INLINE_VAR(detail::crend_::fn, crend) |
4300 | | |
4301 | | NANO_END_NAMESPACE |
4302 | | |
4303 | | #endif |
4304 | | |
4305 | | // nanorange/functional.hpp |
4306 | | // |
4307 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4308 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4309 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4310 | | |
4311 | | #ifndef NANORANGE_FUNCTIONAL_HPP_INCLUDED |
4312 | | #define NANORANGE_FUNCTIONAL_HPP_INCLUDED |
4313 | | |
4314 | | #endif |
4315 | | |
4316 | | #endif |
4317 | | |
4318 | | NANO_BEGIN_NAMESPACE |
4319 | | |
4320 | | // [range.alg.adjacent.find] |
4321 | | |
4322 | | namespace detail { |
4323 | | |
4324 | | struct adjacent_find_fn { |
4325 | | private: |
4326 | | friend struct unique_fn; |
4327 | | |
4328 | | template <typename I, typename S, typename Proj, typename Pred> |
4329 | | static constexpr I impl(I first, S last, Pred& pred, Proj& proj) |
4330 | | { |
4331 | | if (first == last) { |
4332 | | return first; |
4333 | | } |
4334 | | |
4335 | | I next = first; |
4336 | | ++next; |
4337 | | |
4338 | | while (next != last) { |
4339 | | if (nano::invoke(pred, nano::invoke(proj, *first), |
4340 | | nano::invoke(proj, *next))) { |
4341 | | return first; |
4342 | | } |
4343 | | ++first; |
4344 | | ++next; |
4345 | | } |
4346 | | |
4347 | | return next; |
4348 | | } |
4349 | | |
4350 | | public: |
4351 | | template <typename I, |
4352 | | typename S, |
4353 | | typename Proj = identity, |
4354 | | typename Pred = ranges::equal_to> |
4355 | | constexpr std::enable_if_t< |
4356 | | forward_iterator<I> && sentinel_for<S, I> && |
4357 | | indirect_relation<Pred, projected<I, Proj>>, |
4358 | | I> |
4359 | | operator()(I first, |
4360 | | S last, |
4361 | | Pred pred = Pred{}, |
4362 | | Proj proj = Proj{}) const |
4363 | | { |
4364 | | return adjacent_find_fn::impl(std::move(first), std::move(last), |
4365 | | pred, proj); |
4366 | | } |
4367 | | |
4368 | | template <typename Rng, |
4369 | | typename Proj = identity, |
4370 | | typename Pred = ranges::equal_to> |
4371 | | constexpr std::enable_if_t< |
4372 | | forward_range<Rng> && |
4373 | | indirect_relation<Pred, projected<iterator_t<Rng>, Proj>>, |
4374 | | borrowed_iterator_t<Rng>> |
4375 | | operator()(Rng&& rng, Pred pred = Pred{}, Proj proj = Proj{}) const |
4376 | | { |
4377 | | return adjacent_find_fn::impl(nano::begin(rng), nano::end(rng), |
4378 | | pred, proj); |
4379 | | } |
4380 | | }; |
4381 | | |
4382 | | } // namespace detail |
4383 | | |
4384 | | NANO_INLINE_VAR(detail::adjacent_find_fn, adjacent_find) |
4385 | | |
4386 | | NANO_END_NAMESPACE |
4387 | | |
4388 | | #endif |
4389 | | |
4390 | | // nanorange/algorithm/all_of.hpp |
4391 | | // |
4392 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4393 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4394 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4395 | | |
4396 | | #ifndef NANORANGE_ALGORITHM_ALL_OF_HPP_INCLUDED |
4397 | | #define NANORANGE_ALGORITHM_ALL_OF_HPP_INCLUDED |
4398 | | |
4399 | | NANO_BEGIN_NAMESPACE |
4400 | | |
4401 | | // [range.alg.all_of] |
4402 | | |
4403 | | namespace detail { |
4404 | | |
4405 | | struct all_of_fn { |
4406 | | private: |
4407 | | template <typename I, typename S, typename Proj, typename Pred> |
4408 | | static constexpr bool impl(I first, S last, Pred& pred, Proj& proj) |
4409 | | { |
4410 | | while (first != last) { |
4411 | | if (!nano::invoke(pred, nano::invoke(proj, *first))) { |
4412 | | return false; |
4413 | | } |
4414 | | ++first; |
4415 | | } |
4416 | | return true; |
4417 | | } |
4418 | | |
4419 | | public: |
4420 | | template <typename I, |
4421 | | typename S, |
4422 | | typename Proj = identity, |
4423 | | typename Pred> |
4424 | | constexpr std::enable_if_t< |
4425 | | input_iterator<I> && sentinel_for<S, I> && |
4426 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
4427 | | bool> |
4428 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
4429 | | { |
4430 | | return all_of_fn::impl(std::move(first), std::move(last), pred, |
4431 | | proj); |
4432 | | } |
4433 | | |
4434 | | template <typename Rng, typename Proj = identity, typename Pred> |
4435 | | constexpr std::enable_if_t< |
4436 | | input_range<Rng> && |
4437 | | indirect_unary_predicate<Pred, |
4438 | | projected<iterator_t<Rng>, Proj>>, |
4439 | | bool> |
4440 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
4441 | | { |
4442 | | return all_of_fn::impl(nano::begin(rng), nano::end(rng), pred, |
4443 | | proj); |
4444 | | } |
4445 | | }; |
4446 | | |
4447 | | } // namespace detail |
4448 | | |
4449 | | NANO_INLINE_VAR(detail::all_of_fn, all_of) |
4450 | | |
4451 | | NANO_END_NAMESPACE |
4452 | | |
4453 | | #endif |
4454 | | |
4455 | | // nanorange/algorithm/any_of.hpp |
4456 | | // |
4457 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4458 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4459 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4460 | | |
4461 | | #ifndef NANORANGE_ALGORITHM_ANY_OF_HPP_INCLUDED |
4462 | | #define NANORANGE_ALGORITHM_ANY_OF_HPP_INCLUDED |
4463 | | |
4464 | | NANO_BEGIN_NAMESPACE |
4465 | | |
4466 | | // [ranges.alg.any_of] |
4467 | | |
4468 | | namespace detail { |
4469 | | |
4470 | | struct any_of_fn { |
4471 | | private: |
4472 | | friend struct is_permutation_fn; |
4473 | | friend struct none_of_fn; |
4474 | | |
4475 | | template <typename I, typename S, typename Proj, typename Pred> |
4476 | | static constexpr bool impl(I first, S last, Pred& pred, Proj& proj) |
4477 | | { |
4478 | | while (first != last) { |
4479 | | if (nano::invoke(pred, nano::invoke(proj, *first)) == true) { |
4480 | | return true; |
4481 | | } |
4482 | | ++first; |
4483 | | } |
4484 | | return false; |
4485 | | } |
4486 | | |
4487 | | public: |
4488 | | template <typename I, |
4489 | | typename S, |
4490 | | typename Proj = identity, |
4491 | | typename Pred> |
4492 | | constexpr std::enable_if_t< |
4493 | | input_iterator<I> && sentinel_for<S, I> && |
4494 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
4495 | | bool> |
4496 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
4497 | | { |
4498 | | return any_of_fn::impl(std::move(first), std::move(last), pred, |
4499 | | proj); |
4500 | | } |
4501 | | |
4502 | | template <typename Rng, typename Proj = identity, typename Pred> |
4503 | | constexpr std::enable_if_t< |
4504 | | input_range<Rng> && |
4505 | | indirect_unary_predicate<Pred, |
4506 | | projected<iterator_t<Rng>, Proj>>, |
4507 | | bool> |
4508 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
4509 | | { |
4510 | | return any_of_fn::impl(nano::begin(rng), nano::end(rng), pred, |
4511 | | proj); |
4512 | | } |
4513 | | }; |
4514 | | |
4515 | | } // namespace detail |
4516 | | |
4517 | | NANO_INLINE_VAR(detail::any_of_fn, any_of) |
4518 | | |
4519 | | NANO_END_NAMESPACE |
4520 | | |
4521 | | #endif |
4522 | | |
4523 | | // nanorange/algorithm/binary_search.hpp |
4524 | | // |
4525 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4526 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4527 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4528 | | |
4529 | | #ifndef NANORANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED |
4530 | | #define NANORANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED |
4531 | | |
4532 | | // nanorange/algorithm/lower_bound.hpp |
4533 | | // |
4534 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4535 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4536 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4537 | | |
4538 | | #ifndef NANORANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED |
4539 | | #define NANORANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED |
4540 | | |
4541 | | // nanorange/algorithm/partition_point.hpp |
4542 | | // |
4543 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4544 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4545 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4546 | | |
4547 | | // Uses code from CMCSTL2 |
4548 | | |
4549 | | // Copyright Eric Niebler 2014 |
4550 | | // Copyright Casey Carter 2015 |
4551 | | |
4552 | | //===-------------------------- algorithm ---------------------------------===// |
4553 | | // |
4554 | | // The LLVM Compiler Infrastructure |
4555 | | // |
4556 | | // This file is dual licensed under the MIT and the University of Illinois Open |
4557 | | // Source Licenses. See LICENSE.TXT for details. |
4558 | | // |
4559 | | //===----------------------------------------------------------------------===// |
4560 | | // |
4561 | | |
4562 | | #ifndef NANORANGE_ALGORITHM_PARTITION_POINT_HPP_INCLUDED |
4563 | | #define NANORANGE_ALGORITHM_PARTITION_POINT_HPP_INCLUDED |
4564 | | |
4565 | | NANO_BEGIN_NAMESPACE |
4566 | | |
4567 | | namespace detail { |
4568 | | |
4569 | | struct partition_point_fn { |
4570 | | private: |
4571 | | friend struct lower_bound_fn; |
4572 | | friend struct upper_bound_fn; |
4573 | | |
4574 | | template <typename I, typename Pred, typename Proj> |
4575 | | static constexpr I impl_n(I first, |
4576 | | iter_difference_t<I> n, |
4577 | | Pred& pred, |
4578 | | Proj& proj) |
4579 | | { |
4580 | | while (n != 0) { |
4581 | | const auto half = n / 2; |
4582 | | |
4583 | | auto middle = nano::next(first, half); |
4584 | | |
4585 | | if (nano::invoke(pred, nano::invoke(proj, *middle))) { |
4586 | | first = std::move(++middle); |
4587 | | n -= half + 1; |
4588 | | } |
4589 | | else { |
4590 | | n = half; |
4591 | | } |
4592 | | } |
4593 | | |
4594 | | return first; |
4595 | | } |
4596 | | |
4597 | | template <typename I, typename S, typename Pred, typename Proj> |
4598 | | static constexpr std::enable_if_t<sized_sentinel_for<S, I>, I> |
4599 | | impl(I first, S last, Pred& pred, Proj& proj) |
4600 | | { |
4601 | | const auto n = nano::distance(first, std::move(last)); |
4602 | | return partition_point_fn::impl_n(std::move(first), n, pred, proj); |
4603 | | } |
4604 | | |
4605 | | template <typename I, typename S, typename Pred, typename Proj> |
4606 | | static constexpr std::enable_if_t<!sized_sentinel_for<S, I>, I> |
4607 | | impl(I first, S last, Pred& pred, Proj& proj) |
4608 | | { |
4609 | | // Probe exponentially for either end-of-range or an iterator |
4610 | | // that is past the partition point (i.e., does not satisfy pred). |
4611 | | iter_difference_t<I> n{1}; |
4612 | | |
4613 | | while (true) { |
4614 | | auto m = first; |
4615 | | auto d = nano::advance(m, n, last); |
4616 | | if (m == last || !nano::invoke(pred, nano::invoke(proj, *m))) { |
4617 | | n -= d; |
4618 | | return partition_point_fn::impl_n(std::move(first), n, pred, |
4619 | | proj); |
4620 | | } |
4621 | | first = std::move(m); |
4622 | | n *= 2; |
4623 | | } |
4624 | | } |
4625 | | |
4626 | | public: |
4627 | | template <typename I, |
4628 | | typename S, |
4629 | | typename Pred, |
4630 | | typename Proj = identity> |
4631 | | std::enable_if_t<forward_iterator<I> && sentinel_for<S, I> && |
4632 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
4633 | | I> constexpr |
4634 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
4635 | | { |
4636 | | return partition_point_fn::impl(std::move(first), std::move(last), |
4637 | | pred, proj); |
4638 | | } |
4639 | | |
4640 | | template <typename Rng, typename Pred, typename Proj = identity> |
4641 | | std::enable_if_t< |
4642 | | forward_range<Rng> && |
4643 | | indirect_unary_predicate<Pred, |
4644 | | projected<iterator_t<Rng>, Proj>>, |
4645 | | borrowed_iterator_t<Rng>> constexpr |
4646 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
4647 | | { |
4648 | | return partition_point_fn::impl(nano::begin(rng), nano::end(rng), |
4649 | | pred, proj); |
4650 | | } |
4651 | | }; |
4652 | | |
4653 | | } // namespace detail |
4654 | | |
4655 | | NANO_INLINE_VAR(detail::partition_point_fn, partition_point) |
4656 | | |
4657 | | NANO_END_NAMESPACE |
4658 | | |
4659 | | #endif |
4660 | | |
4661 | | NANO_BEGIN_NAMESPACE |
4662 | | |
4663 | | namespace detail { |
4664 | | |
4665 | | struct lower_bound_fn { |
4666 | | private: |
4667 | | friend struct binary_search_fn; |
4668 | | friend struct equal_range_fn; |
4669 | | |
4670 | | template <typename Comp, typename T> |
4671 | | struct compare { |
4672 | | Comp& comp; |
4673 | | const T& val; |
4674 | | |
4675 | | template <typename U> |
4676 | | constexpr bool operator()(U&& u) const |
4677 | | { |
4678 | | return nano::invoke(comp, std::forward<U>(u), val); |
4679 | | } |
4680 | | }; |
4681 | | |
4682 | | template <typename I, |
4683 | | typename S, |
4684 | | typename T, |
4685 | | typename Comp, |
4686 | | typename Proj> |
4687 | | static constexpr I impl(I first, |
4688 | | S last, |
4689 | | const T& value, |
4690 | | Comp& comp, |
4691 | | Proj& proj) |
4692 | | { |
4693 | | const auto comparator = compare<Comp, T>{comp, value}; |
4694 | | return partition_point_fn::impl(std::move(first), std::move(last), |
4695 | | comparator, proj); |
4696 | | } |
4697 | | |
4698 | | public: |
4699 | | template <typename I, |
4700 | | typename S, |
4701 | | typename T, |
4702 | | typename Comp = ranges::less, |
4703 | | typename Proj = identity> |
4704 | | std::enable_if_t< |
4705 | | forward_iterator<I> && sentinel_for<S, I> && |
4706 | | indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>, |
4707 | | I> constexpr |
4708 | | operator()(I first, |
4709 | | S last, |
4710 | | const T& value, |
4711 | | Comp comp = Comp{}, |
4712 | | Proj proj = Proj{}) const |
4713 | | { |
4714 | | return lower_bound_fn::impl(std::move(first), std::move(last), |
4715 | | value, comp, proj); |
4716 | | } |
4717 | | |
4718 | | template <typename Rng, |
4719 | | typename T, |
4720 | | typename Comp = ranges::less, |
4721 | | typename Proj = identity> |
4722 | | std::enable_if_t< |
4723 | | forward_range<Rng> && |
4724 | | indirect_strict_weak_order<Comp, |
4725 | | const T*, |
4726 | | projected<iterator_t<Rng>, Proj>>, |
4727 | | borrowed_iterator_t<Rng>> constexpr |
4728 | | operator()(Rng&& rng, |
4729 | | const T& value, |
4730 | | Comp comp = Comp{}, |
4731 | | Proj proj = Proj{}) const |
4732 | | { |
4733 | | return lower_bound_fn::impl(nano::begin(rng), nano::end(rng), value, |
4734 | | comp, proj); |
4735 | | } |
4736 | | }; |
4737 | | |
4738 | | } // namespace detail |
4739 | | |
4740 | | NANO_INLINE_VAR(detail::lower_bound_fn, lower_bound) |
4741 | | |
4742 | | NANO_END_NAMESPACE |
4743 | | |
4744 | | #endif |
4745 | | |
4746 | | NANO_BEGIN_NAMESPACE |
4747 | | |
4748 | | namespace detail { |
4749 | | |
4750 | | struct binary_search_fn { |
4751 | | private: |
4752 | | template <typename I, |
4753 | | typename S, |
4754 | | typename T, |
4755 | | typename Comp, |
4756 | | typename Proj> |
4757 | | static constexpr bool impl(I first, |
4758 | | S last, |
4759 | | const T& value, |
4760 | | Comp& comp, |
4761 | | Proj& proj) |
4762 | | { |
4763 | | first = |
4764 | | lower_bound_fn::impl(std::move(first), last, value, comp, proj); |
4765 | | return (first != last && |
4766 | | !nano::invoke(comp, value, nano::invoke(proj, *first))); |
4767 | | } |
4768 | | |
4769 | | public: |
4770 | | template <typename I, |
4771 | | typename S, |
4772 | | typename T, |
4773 | | typename Comp = ranges::less, |
4774 | | typename Proj = identity> |
4775 | | std::enable_if_t< |
4776 | | forward_iterator<I> && sentinel_for<S, I> && |
4777 | | indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>, |
4778 | | bool> constexpr |
4779 | | operator()(I first, |
4780 | | S last, |
4781 | | const T& value, |
4782 | | Comp comp = Comp{}, |
4783 | | Proj proj = Proj{}) const |
4784 | | { |
4785 | | return binary_search_fn::impl(std::move(first), std::move(last), |
4786 | | value, comp, proj); |
4787 | | } |
4788 | | |
4789 | | template <typename Rng, |
4790 | | typename T, |
4791 | | typename Comp = ranges::less, |
4792 | | typename Proj = identity> |
4793 | | std::enable_if_t< |
4794 | | forward_range<Rng> && |
4795 | | indirect_strict_weak_order<Comp, |
4796 | | const T*, |
4797 | | projected<iterator_t<Rng>, Proj>>, |
4798 | | bool> constexpr |
4799 | | operator()(Rng&& rng, |
4800 | | const T& value, |
4801 | | Comp comp = Comp{}, |
4802 | | Proj proj = Proj{}) const |
4803 | | { |
4804 | | return binary_search_fn::impl(nano::begin(rng), nano::end(rng), |
4805 | | value, comp, proj); |
4806 | | } |
4807 | | }; |
4808 | | |
4809 | | } // namespace detail |
4810 | | |
4811 | | NANO_INLINE_VAR(detail::binary_search_fn, binary_search) |
4812 | | |
4813 | | NANO_END_NAMESPACE |
4814 | | |
4815 | | #endif |
4816 | | |
4817 | | // nanorange/algorithm/clamp.hpp |
4818 | | // |
4819 | | // Copyright (c) 2020 Boris Staletic (boris dot staletic at gmail dot com) |
4820 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4821 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4822 | | |
4823 | | #ifndef NANORANGE_ALGORITHM_CLAMP_HPP_INCLUDED |
4824 | | #define NANORANGE_ALGORITHM_CLAMP_HPP_INCLUDED |
4825 | | |
4826 | | NANO_BEGIN_NAMESPACE |
4827 | | |
4828 | | namespace detail { |
4829 | | |
4830 | | struct clamp_fn { |
4831 | | template <typename T, |
4832 | | typename Proj = identity, |
4833 | | typename Comp = nano::less> |
4834 | | constexpr std::enable_if_t< |
4835 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
4836 | | const T&> |
4837 | | operator()(const T& value, |
4838 | | const T& low, |
4839 | | const T& high, |
4840 | | Comp comp = {}, |
4841 | | Proj proj = Proj{}) const |
4842 | | { |
4843 | | auto&& projected_value = nano::invoke(proj, value); |
4844 | | if (nano::invoke(comp, projected_value, nano::invoke(proj, low))) { |
4845 | | return low; |
4846 | | } |
4847 | | else if (nano::invoke(comp, nano::invoke(proj, high), |
4848 | | projected_value)) { |
4849 | | return high; |
4850 | | } |
4851 | | else { |
4852 | | return value; |
4853 | | } |
4854 | | } |
4855 | | }; |
4856 | | } // namespace detail |
4857 | | |
4858 | | NANO_INLINE_VAR(detail::clamp_fn, clamp) |
4859 | | |
4860 | | NANO_END_NAMESPACE |
4861 | | |
4862 | | #endif |
4863 | | |
4864 | | // nanorange/algorithm/copy.hpp |
4865 | | // |
4866 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
4867 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4868 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4869 | | |
4870 | | #ifndef NANORANGE_ALGORITHM_COPY_HPP_INCLUDED |
4871 | | #define NANORANGE_ALGORITHM_COPY_HPP_INCLUDED |
4872 | | |
4873 | | // nanorange/detail/algorithm/result_types.hpp |
4874 | | // |
4875 | | // Copyright (c) 2020 Boris Staletic (boris dot staletic at gmail dot com) |
4876 | | // Copyright (c) 2020 Tristan Brindle (tcbrindle at gmail dot com) |
4877 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4878 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
4879 | | |
4880 | | #ifndef NANORANGE_DETAIL_ALGORITHM_RETURN_TYPES |
4881 | | #define NANORANGE_DETAIL_ALGORITHM_RETURN_TYPES |
4882 | | |
4883 | | #include <type_traits> |
4884 | | |
4885 | | NANO_BEGIN_NAMESPACE |
4886 | | |
4887 | | template <typename I, typename F> |
4888 | | struct in_fun_result { |
4889 | | NANO_NO_UNIQUE_ADDRESS I in; |
4890 | | NANO_NO_UNIQUE_ADDRESS F fun; |
4891 | | |
4892 | | template <typename I2, |
4893 | | typename F2, |
4894 | | std::enable_if_t<convertible_to<const I&, I2> && |
4895 | | convertible_to<const F&, F2>, |
4896 | | int> = 0> |
4897 | | constexpr operator in_fun_result<I2, F2>() const& |
4898 | | { |
4899 | | return {in, fun}; |
4900 | | } |
4901 | | |
4902 | | template <typename I2, |
4903 | | typename F2, |
4904 | | std::enable_if_t<convertible_to<I, I2> && convertible_to<F, F2>, |
4905 | | int> = 0> |
4906 | | constexpr operator in_fun_result<I2, F2>() && |
4907 | | { |
4908 | | return {std::move(in), std::move(fun)}; |
4909 | | } |
4910 | | }; |
4911 | | |
4912 | | template <typename I1, typename I2> |
4913 | | struct in_in_result { |
4914 | | NANO_NO_UNIQUE_ADDRESS I1 in1; |
4915 | | NANO_NO_UNIQUE_ADDRESS I2 in2; |
4916 | | |
4917 | | template <typename II1, |
4918 | | typename II2, |
4919 | | std::enable_if_t<convertible_to<const I1&, II1> && |
4920 | | convertible_to<const I2&, II2>, |
4921 | | int> = 0> |
4922 | | constexpr operator in_in_result<II1, II2>() const& |
4923 | | { |
4924 | | return {in1, in2}; |
4925 | | } |
4926 | | |
4927 | | template < |
4928 | | typename II1, |
4929 | | typename II2, |
4930 | | std::enable_if_t<convertible_to<I1, II1> && convertible_to<I2, II2>, |
4931 | | int> = 0> |
4932 | | constexpr operator in_in_result<II1, II2>() && |
4933 | | { |
4934 | | return {std::move(in1), std::move(in2)}; |
4935 | | } |
4936 | | }; |
4937 | | |
4938 | | template <typename I, typename O> |
4939 | | struct in_out_result { |
4940 | | NANO_NO_UNIQUE_ADDRESS I in; |
4941 | | NANO_NO_UNIQUE_ADDRESS O out; |
4942 | | |
4943 | | template <typename I2, |
4944 | | typename O2, |
4945 | | std::enable_if_t<convertible_to<const I&, I2> && |
4946 | | convertible_to<const O&, O2>, |
4947 | | int> = 0> |
4948 | | constexpr operator in_out_result<I2, O2>() const& |
4949 | | { |
4950 | | return {in, out}; |
4951 | | } |
4952 | | |
4953 | | template <typename I2, |
4954 | | typename O2, |
4955 | | std::enable_if_t<convertible_to<I, I2> && convertible_to<O, O2>, |
4956 | | int> = 0> |
4957 | | constexpr operator in_out_result<I2, O2>() && |
4958 | | { |
4959 | | return {std::move(in), std::move(out)}; |
4960 | | } |
4961 | | }; |
4962 | | |
4963 | | template <typename I1, typename I2, typename O> |
4964 | | struct in_in_out_result { |
4965 | | NANO_NO_UNIQUE_ADDRESS I1 in1; |
4966 | | NANO_NO_UNIQUE_ADDRESS I2 in2; |
4967 | | NANO_NO_UNIQUE_ADDRESS O out; |
4968 | | |
4969 | | template <typename II1, |
4970 | | typename II2, |
4971 | | typename O2, |
4972 | | std::enable_if_t<convertible_to<const I1&, II1> && |
4973 | | convertible_to<const I2&, II2> && |
4974 | | convertible_to<const O&, O2>, |
4975 | | int> = 0> |
4976 | | constexpr operator in_in_out_result<II1, II2, O2>() const& |
4977 | | { |
4978 | | return {in1, in2, out}; |
4979 | | } |
4980 | | |
4981 | | template < |
4982 | | typename II1, |
4983 | | typename II2, |
4984 | | typename O2, |
4985 | | std::enable_if_t<convertible_to<I1, II1> && convertible_to<I2, II2> && |
4986 | | convertible_to<O, O2>, |
4987 | | int> = 0> |
4988 | | constexpr operator in_in_out_result<II1, II2, O2>() && |
4989 | | { |
4990 | | return {std::move(in1), std::move(in2), std::move(out)}; |
4991 | | } |
4992 | | }; |
4993 | | |
4994 | | template <typename I, typename O1, typename O2> |
4995 | | struct in_out_out_result { |
4996 | | NANO_NO_UNIQUE_ADDRESS I in; |
4997 | | NANO_NO_UNIQUE_ADDRESS O1 out1; |
4998 | | NANO_NO_UNIQUE_ADDRESS O2 out2; |
4999 | | |
5000 | | template <typename II, |
5001 | | typename OO1, |
5002 | | typename OO2, |
5003 | | std::enable_if_t<convertible_to<const I&, II> && |
5004 | | convertible_to<const O1&, OO1> && |
5005 | | convertible_to<const O2&, OO2>, |
5006 | | int> = 0> |
5007 | | constexpr operator in_out_out_result<II, OO1, OO2>() const& |
5008 | | { |
5009 | | return {in, out1, out2}; |
5010 | | } |
5011 | | |
5012 | | template < |
5013 | | typename II, |
5014 | | typename OO1, |
5015 | | typename OO2, |
5016 | | std::enable_if_t<convertible_to<I, II> && convertible_to<O1, OO1> && |
5017 | | convertible_to<O2, OO2>, |
5018 | | int> = 0> |
5019 | | constexpr operator in_out_out_result<II, OO1, OO2>() && |
5020 | | { |
5021 | | return {std::move(in), std::move(out1), std::move(out2)}; |
5022 | | } |
5023 | | }; |
5024 | | |
5025 | | template <typename T> |
5026 | | struct min_max_result { |
5027 | | NANO_NO_UNIQUE_ADDRESS T min; |
5028 | | NANO_NO_UNIQUE_ADDRESS T max; |
5029 | | |
5030 | | template <typename T2, |
5031 | | std::enable_if_t<convertible_to<const T&, T2>, int> = 0> |
5032 | | constexpr operator min_max_result<T2>() const& |
5033 | | { |
5034 | | return {min, max}; |
5035 | | } |
5036 | | |
5037 | | template <typename T2, std::enable_if_t<convertible_to<T, T2>, int> = 0> |
5038 | | constexpr operator min_max_result<T2>() && |
5039 | | { |
5040 | | return {std::move(min), std::move(max)}; |
5041 | | } |
5042 | | }; |
5043 | | |
5044 | | template <typename I> |
5045 | | struct in_found_result { |
5046 | | NANO_NO_UNIQUE_ADDRESS I in; |
5047 | | bool found; |
5048 | | template <class I2, std::enable_if_t<convertible_to<const I&, I2>, int> = 0> |
5049 | | constexpr operator in_found_result<I2>() const& |
5050 | | { |
5051 | | return {in, found}; |
5052 | | } |
5053 | | template <class I2, std::enable_if_t<convertible_to<const I&, I2>, int> = 0> |
5054 | | constexpr operator in_found_result<I2>() && |
5055 | | { |
5056 | | return {std::move(in), found}; |
5057 | | } |
5058 | | }; |
5059 | | |
5060 | | NANO_END_NAMESPACE |
5061 | | |
5062 | | #endif |
5063 | | |
5064 | | NANO_BEGIN_NAMESPACE |
5065 | | |
5066 | | template <typename I, typename O> |
5067 | | using copy_result = in_out_result<I, O>; |
5068 | | |
5069 | | namespace detail { |
5070 | | |
5071 | | struct copy_fn { |
5072 | | private: |
5073 | | // If we know the distance between first and last, we can use that |
5074 | | // information to (potentially) allow better codegen |
5075 | | template <typename I, typename S, typename O> |
5076 | | static constexpr std::enable_if_t<sized_sentinel_for<S, I>, |
5077 | | copy_result<I, O>> |
5078 | | impl(I first, S last, O result, priority_tag<1>) |
5079 | | { |
5080 | | const auto dist = last - first; |
5081 | | |
5082 | | for (iter_difference_t<I> i = 0; i < dist; ++i) { |
5083 | | *result = *first; |
5084 | | ++first; |
5085 | | ++result; |
5086 | | } |
5087 | | |
5088 | | return {std::move(first), std::move(result)}; |
5089 | | } |
5090 | | |
5091 | | template <typename I, typename S, typename O> |
5092 | | static constexpr copy_result<I, O> impl(I first, |
5093 | | S last, |
5094 | | O result, |
5095 | | priority_tag<0>) |
5096 | | { |
5097 | | while (first != last) { |
5098 | | *result = *first; |
5099 | | ++first; |
5100 | | ++result; |
5101 | | } |
5102 | | |
5103 | | return {std::move(first), std::move(result)}; |
5104 | | } |
5105 | | |
5106 | | public: |
5107 | | template <typename I, typename S, typename O> |
5108 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
5109 | | weakly_incrementable<O> && |
5110 | | indirectly_copyable<I, O>, |
5111 | | copy_result<I, O>> |
5112 | | operator()(I first, S last, O result) const |
5113 | | { |
5114 | | return copy_fn::impl(std::move(first), std::move(last), |
5115 | | std::move(result), priority_tag<1>{}); |
5116 | | } |
5117 | | |
5118 | | template <typename Rng, typename O> |
5119 | | constexpr std::enable_if_t<input_range<Rng> && |
5120 | | weakly_incrementable<O> && |
5121 | | indirectly_copyable<iterator_t<Rng>, O>, |
5122 | | copy_result<borrowed_iterator_t<Rng>, O>> |
5123 | | operator()(Rng&& rng, O result) const |
5124 | | { |
5125 | | return copy_fn::impl(nano::begin(rng), nano::end(rng), |
5126 | | std::move(result), priority_tag<1>{}); |
5127 | | } |
5128 | | }; |
5129 | | |
5130 | | } // namespace detail |
5131 | | |
5132 | | NANO_INLINE_VAR(detail::copy_fn, copy) |
5133 | | |
5134 | | template <typename I, typename O> |
5135 | | using copy_n_result = in_out_result<I, O>; |
5136 | | |
5137 | | namespace detail { |
5138 | | |
5139 | | struct copy_n_fn { |
5140 | | template <typename I, typename O> |
5141 | | constexpr std::enable_if_t<input_iterator<I> && |
5142 | | weakly_incrementable<O> && |
5143 | | indirectly_copyable<I, O>, |
5144 | | copy_n_result<I, O>> |
5145 | | operator()(I first, iter_difference_t<I> n, O result) const |
5146 | | { |
5147 | | for (iter_difference_t<I> i{}; i < n; i++) { |
5148 | | *result = *first; |
5149 | | ++first; |
5150 | | ++result; |
5151 | | } |
5152 | | |
5153 | | return {std::move(first), std::move(result)}; |
5154 | | } |
5155 | | }; |
5156 | | |
5157 | | } // namespace detail |
5158 | | |
5159 | | NANO_INLINE_VAR(detail::copy_n_fn, copy_n) |
5160 | | |
5161 | | template <typename I, typename O> |
5162 | | using copy_if_result = in_out_result<I, O>; |
5163 | | |
5164 | | namespace detail { |
5165 | | |
5166 | | struct copy_if_fn { |
5167 | | private: |
5168 | | template <typename I, |
5169 | | typename S, |
5170 | | typename O, |
5171 | | typename Pred, |
5172 | | typename Proj> |
5173 | | static constexpr copy_if_result<I, O> impl(I first, |
5174 | | S last, |
5175 | | O result, |
5176 | | Pred pred, |
5177 | | Proj proj) |
5178 | | { |
5179 | | while (first != last) { |
5180 | | if (nano::invoke(pred, nano::invoke(proj, *first))) { |
5181 | | *result = *first; |
5182 | | ++result; |
5183 | | } |
5184 | | ++first; |
5185 | | } |
5186 | | |
5187 | | return {std::move(first), std::move(result)}; |
5188 | | } |
5189 | | |
5190 | | public: |
5191 | | template <typename I, |
5192 | | typename S, |
5193 | | typename O, |
5194 | | typename Proj = identity, |
5195 | | typename Pred> |
5196 | | constexpr std::enable_if_t< |
5197 | | input_iterator<I> && sentinel_for<S, I> && |
5198 | | weakly_incrementable<O> && |
5199 | | indirect_unary_predicate<Pred, projected<I, Proj>> && |
5200 | | indirectly_copyable<I, O>, |
5201 | | copy_if_result<I, O>> |
5202 | | operator()(I first, S last, O result, Pred pred, Proj proj = Proj{}) |
5203 | | const |
5204 | | { |
5205 | | return copy_if_fn::impl(std::move(first), std::move(last), |
5206 | | std::move(result), std::move(pred), |
5207 | | std::move(proj)); |
5208 | | } |
5209 | | |
5210 | | template <typename Rng, |
5211 | | typename O, |
5212 | | typename Proj = identity, |
5213 | | typename Pred> |
5214 | | constexpr std::enable_if_t< |
5215 | | input_range<Rng> && weakly_incrementable<O> && |
5216 | | indirect_unary_predicate<Pred, |
5217 | | projected<iterator_t<Rng>, Proj>>, |
5218 | | copy_if_result<borrowed_iterator_t<Rng>, O>> |
5219 | | operator()(Rng&& rng, O result, Pred pred, Proj proj = Proj{}) const |
5220 | | { |
5221 | | return copy_if_fn::impl(nano::begin(rng), nano::end(rng), |
5222 | | std::move(result), std::move(pred), |
5223 | | std::move(proj)); |
5224 | | } |
5225 | | }; |
5226 | | |
5227 | | } // namespace detail |
5228 | | |
5229 | | NANO_INLINE_VAR(detail::copy_if_fn, copy_if) |
5230 | | |
5231 | | template <typename I, typename O> |
5232 | | using copy_backward_result = in_out_result<I, O>; |
5233 | | |
5234 | | namespace detail { |
5235 | | |
5236 | | struct copy_backward_fn { |
5237 | | private: |
5238 | | template <typename I1, typename S1, typename I2> |
5239 | | static constexpr copy_backward_result<I1, I2> impl(I1 first, |
5240 | | S1 last, |
5241 | | I2 result) |
5242 | | { |
5243 | | I1 last_it = nano::next(first, std::move(last)); |
5244 | | I1 it = last_it; |
5245 | | |
5246 | | while (it != first) { |
5247 | | *--result = *--it; |
5248 | | } |
5249 | | |
5250 | | return {std::move(last_it), std::move(result)}; |
5251 | | } |
5252 | | |
5253 | | public: |
5254 | | template <typename I1, typename S1, typename I2> |
5255 | | constexpr std::enable_if_t< |
5256 | | bidirectional_iterator<I1> && sentinel_for<S1, I1> && |
5257 | | bidirectional_iterator<I2> && indirectly_copyable<I1, I2>, |
5258 | | copy_backward_result<I1, I2>> |
5259 | | operator()(I1 first, S1 last, I2 result) const |
5260 | | { |
5261 | | return copy_backward_fn::impl(std::move(first), std::move(last), |
5262 | | std::move(result)); |
5263 | | } |
5264 | | |
5265 | | template <typename Rng, typename I> |
5266 | | constexpr std::enable_if_t< |
5267 | | bidirectional_range<Rng> && bidirectional_iterator<I> && |
5268 | | indirectly_copyable<iterator_t<Rng>, I>, |
5269 | | copy_backward_result<borrowed_iterator_t<Rng>, I>> |
5270 | | operator()(Rng&& rng, I result) const |
5271 | | { |
5272 | | return copy_backward_fn::impl(nano::begin(rng), nano::end(rng), |
5273 | | std::move(result)); |
5274 | | } |
5275 | | }; |
5276 | | |
5277 | | } // namespace detail |
5278 | | |
5279 | | NANO_INLINE_VAR(detail::copy_backward_fn, copy_backward) |
5280 | | |
5281 | | NANO_END_NAMESPACE |
5282 | | |
5283 | | #endif |
5284 | | |
5285 | | // nanorange/algorithm/count.hpp |
5286 | | // |
5287 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5288 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5289 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5290 | | |
5291 | | #ifndef NANORANGE_ALGORITHM_COUNT_HPP_INCLUDED |
5292 | | #define NANORANGE_ALGORITHM_COUNT_HPP_INCLUDED |
5293 | | |
5294 | | NANO_BEGIN_NAMESPACE |
5295 | | |
5296 | | // [rng.alg.count] |
5297 | | |
5298 | | namespace detail { |
5299 | | |
5300 | | struct count_if_fn { |
5301 | | private: |
5302 | | friend struct count_fn; |
5303 | | friend struct is_permutation_fn; |
5304 | | |
5305 | | template <typename I, typename S, typename Proj, typename Pred> |
5306 | | static constexpr iter_difference_t<I> impl(I first, |
5307 | | S last, |
5308 | | Pred& pred, |
5309 | | Proj& proj) |
5310 | | { |
5311 | | iter_difference_t<I> counter = 0; |
5312 | | |
5313 | | for (; first != last; ++first) { |
5314 | | if (nano::invoke(pred, nano::invoke(proj, *first))) { |
5315 | | ++counter; |
5316 | | } |
5317 | | } |
5318 | | |
5319 | | return counter; |
5320 | | } |
5321 | | |
5322 | | public: |
5323 | | template <typename I, |
5324 | | typename S, |
5325 | | typename Proj = identity, |
5326 | | typename Pred> |
5327 | | constexpr std::enable_if_t< |
5328 | | input_iterator<I> && sentinel_for<S, I> && |
5329 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
5330 | | iter_difference_t<I>> |
5331 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
5332 | | { |
5333 | | return count_if_fn::impl(std::move(first), std::move(last), pred, |
5334 | | proj); |
5335 | | } |
5336 | | |
5337 | | template <typename Rng, typename Proj = identity, typename Pred> |
5338 | | constexpr std::enable_if_t< |
5339 | | input_range<Rng> && |
5340 | | indirect_unary_predicate<Pred, |
5341 | | projected<iterator_t<Rng>, Proj>>, |
5342 | | range_difference_t<Rng>> |
5343 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
5344 | | { |
5345 | | return count_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
5346 | | proj); |
5347 | | } |
5348 | | }; |
5349 | | } // namespace detail |
5350 | | |
5351 | | NANO_INLINE_VAR(detail::count_if_fn, count_if) |
5352 | | |
5353 | | namespace detail { |
5354 | | |
5355 | | struct count_fn { |
5356 | | template <typename I, typename S, typename T, typename Proj = identity> |
5357 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
5358 | | indirect_relation<ranges::equal_to, |
5359 | | projected<I, Proj>, |
5360 | | const T*>, |
5361 | | iter_difference_t<I>> |
5362 | | operator()(I first, S last, const T& value, Proj proj = Proj{}) const |
5363 | | { |
5364 | | const auto pred = [&value](const auto& t) { return t == value; }; |
5365 | | return count_if_fn::impl(std::move(first), std::move(last), pred, |
5366 | | proj); |
5367 | | } |
5368 | | |
5369 | | template <typename Rng, typename T, typename Proj = identity> |
5370 | | constexpr std::enable_if_t< |
5371 | | input_range<Rng> && |
5372 | | indirect_relation<ranges::equal_to, |
5373 | | projected<iterator_t<Rng>, Proj>, |
5374 | | const T*>, |
5375 | | range_difference_t<Rng>> |
5376 | | operator()(Rng&& rng, const T& value, Proj proj = Proj{}) const |
5377 | | { |
5378 | | const auto pred = [&value](const auto& t) { return t == value; }; |
5379 | | return count_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
5380 | | proj); |
5381 | | } |
5382 | | }; |
5383 | | |
5384 | | } // namespace detail |
5385 | | |
5386 | | NANO_INLINE_VAR(detail::count_fn, count) |
5387 | | |
5388 | | NANO_END_NAMESPACE |
5389 | | |
5390 | | #endif |
5391 | | |
5392 | | // nanorange/algorithm/equal.hpp |
5393 | | // |
5394 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5395 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5396 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5397 | | |
5398 | | #ifndef NANORANGE_ALGORITHM_EQUAL_HPP_INCLUDED |
5399 | | #define NANORANGE_ALGORITHM_EQUAL_HPP_INCLUDED |
5400 | | |
5401 | | NANO_BEGIN_NAMESPACE |
5402 | | |
5403 | | namespace detail { |
5404 | | |
5405 | | struct equal_fn { |
5406 | | private: |
5407 | | template <typename I1, |
5408 | | typename S1, |
5409 | | typename I2, |
5410 | | typename S2, |
5411 | | typename Pred, |
5412 | | typename Proj1, |
5413 | | typename Proj2> |
5414 | | static constexpr bool impl4(I1 first1, |
5415 | | S1 last1, |
5416 | | I2 first2, |
5417 | | S2 last2, |
5418 | | Pred& pred, |
5419 | | Proj1& proj1, |
5420 | | Proj2& proj2) |
5421 | | { |
5422 | | while (first1 != last1 && first2 != last2) { |
5423 | | if (!nano::invoke(pred, nano::invoke(proj1, *first1), |
5424 | | nano::invoke(proj2, *first2))) { |
5425 | | return false; |
5426 | | } |
5427 | | ++first1; |
5428 | | ++first2; |
5429 | | } |
5430 | | |
5431 | | return first1 == last1 && first2 == last2; |
5432 | | } |
5433 | | |
5434 | | template <typename I1, |
5435 | | typename S1, |
5436 | | typename I2, |
5437 | | typename Pred, |
5438 | | typename Proj1, |
5439 | | typename Proj2> |
5440 | | static constexpr bool impl3(I1 first1, |
5441 | | S1 last1, |
5442 | | I2 first2, |
5443 | | Pred pred, |
5444 | | Proj1& proj1, |
5445 | | Proj2& proj2) |
5446 | | { |
5447 | | while (first1 != last1) { |
5448 | | if (!nano::invoke(pred, nano::invoke(proj1, *first1), |
5449 | | nano::invoke(proj2, *first2))) { |
5450 | | return false; |
5451 | | } |
5452 | | ++first1; |
5453 | | ++first2; |
5454 | | } |
5455 | | |
5456 | | return true; |
5457 | | } |
5458 | | |
5459 | | public: |
5460 | | // Four-legged, sized sentinels |
5461 | | template <typename I1, |
5462 | | typename S1, |
5463 | | typename I2, |
5464 | | typename S2, |
5465 | | typename Pred = ranges::equal_to, |
5466 | | typename Proj1 = identity, |
5467 | | typename Proj2 = identity> |
5468 | | constexpr std::enable_if_t< |
5469 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
5470 | | sentinel_for<S2, I2> && |
5471 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2> && |
5472 | | sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>, |
5473 | | bool> |
5474 | | operator()(I1 first1, |
5475 | | S1 last1, |
5476 | | I2 first2, |
5477 | | S2 last2, |
5478 | | Pred pred = Pred{}, |
5479 | | Proj1 proj1 = Proj1{}, |
5480 | | Proj2 proj2 = Proj2{}) const |
5481 | | { |
5482 | | if (last1 - first1 != last2 - first2) { |
5483 | | return false; |
5484 | | } |
5485 | | |
5486 | | // Ranges are the same size, so call the 3-legged version |
5487 | | // and save ourselves a comparison |
5488 | | return equal_fn::impl3(std::move(first1), std::move(last1), |
5489 | | std::move(first2), pred, proj1, proj2); |
5490 | | } |
5491 | | |
5492 | | // Four-legged, unsized sentinels |
5493 | | template <typename I1, |
5494 | | typename S1, |
5495 | | typename I2, |
5496 | | typename S2, |
5497 | | typename Pred = ranges::equal_to, |
5498 | | typename Proj1 = identity, |
5499 | | typename Proj2 = identity> |
5500 | | constexpr std::enable_if_t< |
5501 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
5502 | | sentinel_for<S2, I2> && |
5503 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2> && |
5504 | | !(sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>), |
5505 | | bool> |
5506 | | operator()(I1 first1, |
5507 | | S1 last1, |
5508 | | I2 first2, |
5509 | | S2 last2, |
5510 | | Pred pred = Pred{}, |
5511 | | Proj1 proj1 = Proj1{}, |
5512 | | Proj2 proj2 = Proj2{}) const |
5513 | | { |
5514 | | return equal_fn::impl4(std::move(first1), std::move(last1), |
5515 | | std::move(first2), std::move(last2), pred, |
5516 | | proj1, proj2); |
5517 | | } |
5518 | | |
5519 | | // Three legged |
5520 | | template <typename I1, |
5521 | | typename S1, |
5522 | | typename I2, |
5523 | | typename Pred = ranges::equal_to, |
5524 | | typename Proj1 = identity, |
5525 | | typename Proj2 = identity> |
5526 | | NANO_DEPRECATED constexpr std::enable_if_t< |
5527 | | input_iterator<I1> && sentinel_for<S1, I1> && |
5528 | | input_iterator<std::decay_t<I2>> && !input_range<I2> && |
5529 | | indirectly_comparable<I1, std::decay_t<I2>, Pred, Proj1, Proj2>, |
5530 | | bool> |
5531 | | operator()(I1 first1, |
5532 | | S1 last1, |
5533 | | I2 first2, |
5534 | | Pred pred = Pred{}, |
5535 | | Proj1 proj1 = Proj1{}, |
5536 | | Proj2 proj2 = Proj2{}) const |
5537 | | { |
5538 | | return equal_fn::impl3(std::move(first1), std::move(last1), |
5539 | | std::forward<I2>(first2), pred, proj1, |
5540 | | proj2); |
5541 | | } |
5542 | | |
5543 | | // Two ranges, both sized |
5544 | | template <typename Rng1, |
5545 | | typename Rng2, |
5546 | | typename Pred = ranges::equal_to, |
5547 | | typename Proj1 = identity, |
5548 | | typename Proj2 = identity> |
5549 | | constexpr std::enable_if_t<input_range<Rng1> && input_range<Rng2> && |
5550 | | indirectly_comparable<iterator_t<Rng1>, |
5551 | | iterator_t<Rng2>, |
5552 | | Pred, |
5553 | | Proj1, |
5554 | | Proj2> && |
5555 | | sized_range<Rng1> && sized_range<Rng2>, |
5556 | | bool> |
5557 | | operator()(Rng1&& rng1, |
5558 | | Rng2&& rng2, |
5559 | | Pred pred = Pred{}, |
5560 | | Proj1 proj1 = Proj1{}, |
5561 | | Proj2 proj2 = Proj2{}) const |
5562 | | { |
5563 | | if (nano::distance(rng1) != nano::distance(rng2)) { |
5564 | | return false; |
5565 | | } |
5566 | | |
5567 | | return equal_fn::impl3(nano::begin(rng1), nano::end(rng1), |
5568 | | nano::begin(rng2), pred, proj1, proj2); |
5569 | | } |
5570 | | |
5571 | | // Two ranges, not both sized |
5572 | | template <typename Rng1, |
5573 | | typename Rng2, |
5574 | | typename Pred = ranges::equal_to, |
5575 | | typename Proj1 = identity, |
5576 | | typename Proj2 = identity> |
5577 | | constexpr std::enable_if_t<input_range<Rng1> && input_range<Rng2> && |
5578 | | indirectly_comparable<iterator_t<Rng1>, |
5579 | | iterator_t<Rng2>, |
5580 | | Pred, |
5581 | | Proj1, |
5582 | | Proj2> && |
5583 | | !(sized_range<Rng1> && |
5584 | | sized_range<Rng2>), |
5585 | | bool> |
5586 | | operator()(Rng1&& rng1, |
5587 | | Rng2&& rng2, |
5588 | | Pred pred = Pred{}, |
5589 | | Proj1 proj1 = Proj1{}, |
5590 | | Proj2 proj2 = Proj2{}) const |
5591 | | { |
5592 | | return equal_fn::impl4(nano::begin(rng1), nano::end(rng1), |
5593 | | nano::begin(rng2), nano::end(rng2), pred, |
5594 | | proj1, proj2); |
5595 | | } |
5596 | | |
5597 | | // Range and a half |
5598 | | template <typename Rng1, |
5599 | | typename I2, |
5600 | | typename Pred = ranges::equal_to, |
5601 | | typename Proj1 = identity, |
5602 | | typename Proj2 = identity> |
5603 | | NANO_DEPRECATED constexpr std::enable_if_t< |
5604 | | input_range<Rng1> && input_iterator<std::decay_t<I2>> && |
5605 | | !input_range<I2> && |
5606 | | indirectly_comparable<iterator_t<Rng1>, |
5607 | | std::decay_t<I2>, |
5608 | | Pred, |
5609 | | Proj1, |
5610 | | Proj2>, |
5611 | | bool> |
5612 | | operator()(Rng1&& rng1, |
5613 | | I2&& first2, |
5614 | | Pred pred = Pred{}, |
5615 | | Proj1 proj1 = Proj1{}, |
5616 | | Proj2 proj2 = Proj2{}) const |
5617 | | { |
5618 | | return equal_fn::impl3(nano::begin(rng1), nano::end(rng1), |
5619 | | std::forward<I2>(first2), pred, proj1, |
5620 | | proj2); |
5621 | | } |
5622 | | }; |
5623 | | |
5624 | | } // namespace detail |
5625 | | |
5626 | | NANO_INLINE_VAR(detail::equal_fn, equal) |
5627 | | |
5628 | | NANO_END_NAMESPACE |
5629 | | |
5630 | | #endif |
5631 | | |
5632 | | // nanorange/algorithm/equal_range.hpp |
5633 | | // |
5634 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5635 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5636 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5637 | | |
5638 | | #ifndef NANORANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED |
5639 | | #define NANORANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED |
5640 | | |
5641 | | // nanorange/algorithm/upper_bound.hpp |
5642 | | // |
5643 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5644 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5645 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5646 | | |
5647 | | #ifndef NANORANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED |
5648 | | #define NANORANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED |
5649 | | |
5650 | | NANO_BEGIN_NAMESPACE |
5651 | | |
5652 | | namespace detail { |
5653 | | |
5654 | | struct upper_bound_fn { |
5655 | | private: |
5656 | | friend struct equal_range_fn; |
5657 | | |
5658 | | template <typename Comp, typename T> |
5659 | | struct compare { |
5660 | | Comp& comp; |
5661 | | const T& val; |
5662 | | |
5663 | | template <typename U> |
5664 | | constexpr bool operator()(U&& u) const |
5665 | | { |
5666 | | return !nano::invoke(comp, val, std::forward<U>(u)); |
5667 | | } |
5668 | | }; |
5669 | | |
5670 | | template <typename I, |
5671 | | typename S, |
5672 | | typename T, |
5673 | | typename Comp, |
5674 | | typename Proj> |
5675 | | static constexpr I impl(I first, |
5676 | | S last, |
5677 | | const T& value, |
5678 | | Comp& comp, |
5679 | | Proj& proj) |
5680 | | { |
5681 | | const auto comparator = compare<Comp, T>{comp, value}; |
5682 | | return partition_point_fn::impl(std::move(first), std::move(last), |
5683 | | comparator, proj); |
5684 | | } |
5685 | | |
5686 | | public: |
5687 | | template <typename I, |
5688 | | typename S, |
5689 | | typename T, |
5690 | | typename Comp = ranges::less, |
5691 | | typename Proj = identity> |
5692 | | std::enable_if_t< |
5693 | | forward_iterator<I> && sentinel_for<S, I> && |
5694 | | indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>, |
5695 | | I> constexpr |
5696 | | operator()(I first, |
5697 | | S last, |
5698 | | const T& value, |
5699 | | Comp comp = Comp{}, |
5700 | | Proj proj = Proj{}) const |
5701 | | { |
5702 | | return upper_bound_fn::impl(std::move(first), std::move(last), |
5703 | | value, comp, proj); |
5704 | | } |
5705 | | |
5706 | | template <typename Rng, |
5707 | | typename T, |
5708 | | typename Comp = ranges::less, |
5709 | | typename Proj = identity> |
5710 | | std::enable_if_t< |
5711 | | forward_range<Rng> && |
5712 | | indirect_strict_weak_order<Comp, |
5713 | | const T*, |
5714 | | projected<iterator_t<Rng>, Proj>>, |
5715 | | borrowed_iterator_t<Rng>> constexpr |
5716 | | operator()(Rng&& rng, |
5717 | | const T& value, |
5718 | | Comp comp = Comp{}, |
5719 | | Proj proj = Proj{}) const |
5720 | | { |
5721 | | return upper_bound_fn::impl(nano::begin(rng), nano::end(rng), value, |
5722 | | comp, proj); |
5723 | | } |
5724 | | }; |
5725 | | |
5726 | | } // namespace detail |
5727 | | |
5728 | | NANO_INLINE_VAR(detail::upper_bound_fn, upper_bound) |
5729 | | |
5730 | | NANO_END_NAMESPACE |
5731 | | |
5732 | | #endif |
5733 | | |
5734 | | // nanorange/views/subrange.hpp |
5735 | | // |
5736 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5737 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5738 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5739 | | |
5740 | | #ifndef NANORANGE_VIEWS_SUBRANGE_HPP_INCLUDED |
5741 | | #define NANORANGE_VIEWS_SUBRANGE_HPP_INCLUDED |
5742 | | |
5743 | | // nanorange/views/interface.hpp |
5744 | | // |
5745 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5746 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5747 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5748 | | |
5749 | | #ifndef NANORANGE_VIEWS_INTERFACE_HPP_INCLUDED |
5750 | | #define NANORANGE_VIEWS_INTERFACE_HPP_INCLUDED |
5751 | | |
5752 | | // nanorange/iterator/common_iterator.hpp |
5753 | | // |
5754 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5755 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5756 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5757 | | |
5758 | | #ifndef NANORANGE_ITERATOR_COMMON_ITERATOR_HPP_INCLUDED |
5759 | | #define NANORANGE_ITERATOR_COMMON_ITERATOR_HPP_INCLUDED |
5760 | | |
5761 | | // nanorange/iterator/concepts.hpp |
5762 | | // |
5763 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
5764 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5765 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5766 | | |
5767 | | #ifndef NANORANGE_ITERATOR_CONCEPTS_HPP_INCLUDED |
5768 | | #define NANORANGE_ITERATOR_CONCEPTS_HPP_INCLUDED |
5769 | | |
5770 | | #endif |
5771 | | |
5772 | | NANO_BEGIN_NAMESPACE |
5773 | | |
5774 | | // [range.iterators.common] |
5775 | | |
5776 | | namespace common_iterator_ { |
5777 | | |
5778 | | template <typename I, typename S> |
5779 | | class common_iterator { |
5780 | | static_assert(input_or_output_iterator<I>, ""); |
5781 | | static_assert(sentinel_for<S, I>, ""); |
5782 | | static_assert(!same_as<I, S>, ""); |
5783 | | |
5784 | | template <typename II, typename SS> |
5785 | | friend class common_iterator; |
5786 | | |
5787 | | class op_arrow_proxy { |
5788 | | iter_value_t<I> keep_; |
5789 | | |
5790 | | constexpr op_arrow_proxy(iter_reference_t<I>&& x) |
5791 | | : keep_(std::move(x)) |
5792 | | { |
5793 | | } |
5794 | | |
5795 | | public: |
5796 | | constexpr const iter_value_t<I>* operator->() const |
5797 | | { |
5798 | | return std::addressof(keep_); |
5799 | | } |
5800 | | }; |
5801 | | |
5802 | | template <typename II> |
5803 | | using op_arrow_t = decltype(std::declval<const II&>().operator->()); |
5804 | | |
5805 | | template <typename II> |
5806 | | static constexpr auto do_op_arrow(const II& i, detail::priority_tag<2>) |
5807 | | -> std::enable_if_t<std::is_pointer<II>::value || |
5808 | | detail::exists_v<op_arrow_t, II>, |
5809 | | I> |
5810 | | { |
5811 | | return i; |
5812 | | } |
5813 | | |
5814 | | template <typename II> |
5815 | | static constexpr auto do_op_arrow(const II& i, detail::priority_tag<1>) |
5816 | | -> std::enable_if_t< |
5817 | | std::is_reference<iter_reference_t<const II>>::value, |
5818 | | std::add_pointer_t<iter_reference_t<const II>>> |
5819 | | { |
5820 | | auto&& tmp = *i; |
5821 | | return std::addressof(tmp); |
5822 | | } |
5823 | | |
5824 | | template <typename II> |
5825 | | static constexpr auto do_op_arrow(const II& i, detail::priority_tag<0>) |
5826 | | -> op_arrow_proxy |
5827 | | { |
5828 | | return {i}; |
5829 | | } |
5830 | | |
5831 | | public: |
5832 | | using difference_type = iter_difference_t<I>; |
5833 | | |
5834 | | constexpr common_iterator() : is_sentinel_{false}, iter_{} {} |
5835 | | |
5836 | | constexpr common_iterator(I i) : is_sentinel_{false}, iter_(i) {} |
5837 | | |
5838 | | constexpr common_iterator(S s) : is_sentinel_{true}, sentinel_{s} {} |
5839 | | |
5840 | | template < |
5841 | | typename II, |
5842 | | typename SS, |
5843 | | std::enable_if_t<convertible_to<II, I> && convertible_to<SS, S>, |
5844 | | int> = 0> |
5845 | | constexpr common_iterator(const common_iterator<II, SS>& other) |
5846 | | : is_sentinel_{other.is_sentinel_}, |
5847 | | iter_(other.iter_), |
5848 | | sentinel_(other.sentinel_) |
5849 | | { |
5850 | | } |
5851 | | |
5852 | | template <typename II, typename SS> |
5853 | | constexpr std::enable_if_t<convertible_to<II, I> && |
5854 | | convertible_to<SS, S>, |
5855 | | common_iterator&> |
5856 | | operator=(const common_iterator<II, SS>& other) |
5857 | | { |
5858 | | is_sentinel_ = other.is_sentinel_; |
5859 | | iter_ = other.iter_; |
5860 | | sentinel_ = other.sentinel_; |
5861 | | return *this; |
5862 | | } |
5863 | | |
5864 | | constexpr decltype(auto) operator*() |
5865 | | { |
5866 | | return *iter_; |
5867 | | } |
5868 | | |
5869 | | template <typename II = I, |
5870 | | std::enable_if_t<detail::dereferenceable<const I>, int> = 0> |
5871 | | constexpr decltype(auto) operator*() const |
5872 | | { |
5873 | | return *iter_; |
5874 | | } |
5875 | | |
5876 | | template <typename II = I> |
5877 | | constexpr auto operator->() const |
5878 | | -> decltype(common_iterator::do_op_arrow(std::declval<const II&>(), |
5879 | | detail::priority_tag<2>{})) |
5880 | | { |
5881 | | return do_op_arrow(iter_, detail::priority_tag<2>{}); |
5882 | | } |
5883 | | |
5884 | | constexpr common_iterator& operator++() |
5885 | | { |
5886 | | ++iter_; |
5887 | | return *this; |
5888 | | } |
5889 | | |
5890 | | template <typename II = I, |
5891 | | std::enable_if_t<!forward_iterator<II>, int> = 0> |
5892 | | constexpr decltype(auto) operator++(int) |
5893 | | { |
5894 | | return iter_++; |
5895 | | } |
5896 | | |
5897 | | template <typename II = I, |
5898 | | std::enable_if_t<forward_iterator<II>, int> = 0> |
5899 | | constexpr common_iterator operator++(int) |
5900 | | { |
5901 | | common_iterator tmp = *this; |
5902 | | ++iter_; |
5903 | | return tmp; |
5904 | | } |
5905 | | |
5906 | | template <typename I2, typename S2> |
5907 | | friend constexpr auto operator==(const common_iterator& x, |
5908 | | const common_iterator<I2, S2>& y) |
5909 | | -> std::enable_if_t<sentinel_for<S2, I> && sentinel_for<S, I2> && |
5910 | | !equality_comparable_with<I, I2>, |
5911 | | bool> |
5912 | | { |
5913 | | return x.is_sentinel_ ? (y.is_sentinel_ || y.iter_ == x.sentinel_) |
5914 | | : (!y.is_sentinel_ || x.iter_ == y.sentinel_); |
5915 | | } |
5916 | | |
5917 | | template <typename I2, typename S2> |
5918 | | friend constexpr auto operator==(const common_iterator& x, |
5919 | | const common_iterator<I2, S2>& y) |
5920 | | -> std::enable_if_t<sentinel_for<S2, I> && sentinel_for<S, I2> && |
5921 | | equality_comparable_with<I, I2>, |
5922 | | bool> |
5923 | | { |
5924 | | return x.is_sentinel_ ? (y.is_sentinel_ || y.iter_ == x.sentinel_) |
5925 | | : (y.is_sentinel_ ? x.iter_ == y.sentinel_ |
5926 | | : x.iter_ == y.iter_); |
5927 | | } |
5928 | | |
5929 | | template <typename I2, typename S2> |
5930 | | friend constexpr auto operator!=(const common_iterator& x, |
5931 | | const common_iterator<I2, S2>& y) |
5932 | | -> std::enable_if_t<sentinel_for<S2, I> && sentinel_for<S, I2>, |
5933 | | bool> |
5934 | | { |
5935 | | return !(x == y); |
5936 | | } |
5937 | | |
5938 | | template <typename I2, typename S2> |
5939 | | friend constexpr auto operator-(const common_iterator& x, |
5940 | | const common_iterator<I2, S2>& y) |
5941 | | -> std::enable_if_t<sized_sentinel_for<I, I2> && |
5942 | | sized_sentinel_for<S, I2> && |
5943 | | sized_sentinel_for<S, I2>, |
5944 | | iter_difference_t<I2>> |
5945 | | { |
5946 | | return x.is_sentinel_ ? (y.is_sentinel_ ? 0 : x.sentinel_ - y.iter_) |
5947 | | : (y.is_sentinel_ ? x.iter_ - y.sentinel_ |
5948 | | : x.iter_ - y.iter_); |
5949 | | } |
5950 | | |
5951 | | friend constexpr iter_rvalue_reference_t<I> iter_move( |
5952 | | const common_iterator& i) |
5953 | | { |
5954 | | return ranges::iter_move(i.iter_); |
5955 | | } |
5956 | | |
5957 | | template <typename I2, typename S2> |
5958 | | friend constexpr std::enable_if_t<indirectly_swappable<I2, I>> |
5959 | | iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y) |
5960 | | { |
5961 | | return ranges::iter_swap(x.iter_, y.iter_); |
5962 | | } |
5963 | | |
5964 | | // private: |
5965 | | // TODO: Some sort of variant-like union |
5966 | | bool is_sentinel_{}; |
5967 | | I iter_{}; |
5968 | | S sentinel_{}; |
5969 | | }; |
5970 | | |
5971 | | } // namespace common_iterator_ |
5972 | | |
5973 | | using common_iterator_::common_iterator; |
5974 | | |
5975 | | template <typename I, typename S> |
5976 | | struct readable_traits<common_iterator<I, S>> { |
5977 | | using value_type = iter_value_t<I>; |
5978 | | }; |
5979 | | |
5980 | | template <typename I, typename S> |
5981 | | struct iterator_category<common_iterator<I, S>> |
5982 | | : std::conditional<forward_iterator<I>, |
5983 | | forward_iterator_tag, |
5984 | | input_iterator_tag> {}; |
5985 | | |
5986 | | NANO_END_NAMESPACE |
5987 | | |
5988 | | namespace std { |
5989 | | |
5990 | | template <typename I, typename S> |
5991 | | struct iterator_traits<::nano::common_iterator<I, S>> { |
5992 | | using difference_type = |
5993 | | ::nano::iter_difference_t<::nano::common_iterator<I, S>>; |
5994 | | using value_type = ::nano::iter_value_t<::nano::common_iterator<I, S>>; |
5995 | | using pointer = std::add_pointer_t< |
5996 | | ::nano::iter_reference_t<::nano::common_iterator<I, S>>>; |
5997 | | using reference = |
5998 | | ::nano::iter_reference_t<::nano::common_iterator<I, S>>; |
5999 | | using iterator_category = |
6000 | | ::nano::detail::conditional_t<::nano::forward_iterator<I>, |
6001 | | std::forward_iterator_tag, |
6002 | | std::input_iterator_tag>; |
6003 | | }; |
6004 | | |
6005 | | } // namespace std |
6006 | | |
6007 | | #endif |
6008 | | |
6009 | | NANO_BEGIN_NAMESPACE |
6010 | | |
6011 | | // [ranges.view_interface] |
6012 | | |
6013 | | namespace detail { |
6014 | | |
6015 | | template <typename, typename = void> |
6016 | | struct range_common_iterator_impl; |
6017 | | |
6018 | | template <typename R> |
6019 | | struct range_common_iterator_impl< |
6020 | | R, |
6021 | | std::enable_if_t<range<R> && !common_range<R>>> { |
6022 | | using type = common_iterator<iterator_t<R>, sentinel_t<R>>; |
6023 | | }; |
6024 | | |
6025 | | template <typename R> |
6026 | | struct range_common_iterator_impl<R, std::enable_if_t<common_range<R>>> { |
6027 | | using type = iterator_t<R>; |
6028 | | }; |
6029 | | |
6030 | | template <typename R> |
6031 | | using range_common_iterator_t = |
6032 | | typename range_common_iterator_impl<R>::type; |
6033 | | |
6034 | | } // namespace detail |
6035 | | |
6036 | | template <typename D> |
6037 | | class view_interface : public view_base { |
6038 | | static_assert(std::is_class<D>::value, ""); |
6039 | | static_assert(same_as<D, std::remove_cv_t<D>>, ""); |
6040 | | |
6041 | | private: |
6042 | | constexpr D& derived() noexcept |
6043 | 44.7M | { |
6044 | 44.7M | return static_cast<D&>(*this); |
6045 | 44.7M | } nano::ranges::view_interface<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::derived() Line | Count | Source | 6043 | 36.6M | { | 6044 | 36.6M | return static_cast<D&>(*this); | 6045 | 36.6M | } |
nano::ranges::view_interface<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::derived() Line | Count | Source | 6043 | 8.19M | { | 6044 | 8.19M | return static_cast<D&>(*this); | 6045 | 8.19M | } |
|
6046 | | |
6047 | | constexpr const D& derived() const noexcept |
6048 | 33.9M | { |
6049 | 33.9M | return static_cast<const D&>(*this); |
6050 | 33.9M | } nano::ranges::view_interface<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::derived() const Line | Count | Source | 6048 | 23.3M | { | 6049 | 23.3M | return static_cast<const D&>(*this); | 6050 | 23.3M | } |
nano::ranges::view_interface<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::derived() const Line | Count | Source | 6048 | 10.5M | { | 6049 | 10.5M | return static_cast<const D&>(*this); | 6050 | 10.5M | } |
|
6051 | | |
6052 | | public: |
6053 | | template <typename R = D> |
6054 | | [[nodiscard]] constexpr auto empty() |
6055 | | -> std::enable_if_t<forward_range<R>, bool> |
6056 | | { |
6057 | | return ranges::begin(derived()) == ranges::end(derived()); |
6058 | | } |
6059 | | |
6060 | | template <typename R = D> |
6061 | | [[nodiscard]] constexpr auto empty() const |
6062 | | -> std::enable_if_t<forward_range<const R>, bool> |
6063 | | { |
6064 | | return ranges::begin(derived()) == ranges::end(derived()); |
6065 | | } |
6066 | | |
6067 | | template <typename R = D, |
6068 | | typename = decltype(ranges::empty(std::declval<R&>()))> |
6069 | | constexpr explicit operator bool() |
6070 | | { |
6071 | | return !ranges::empty(derived()); |
6072 | | } |
6073 | | |
6074 | | template <typename R = D, |
6075 | | typename = decltype(ranges::empty(std::declval<const R&>()))> |
6076 | | constexpr explicit operator bool() const |
6077 | | { |
6078 | | return !ranges::empty(derived()); |
6079 | | } |
6080 | | |
6081 | | template <typename R = D, |
6082 | | typename = std::enable_if_t<contiguous_iterator<iterator_t<R>>>> |
6083 | | constexpr auto data() |
6084 | 22.4M | { |
6085 | 22.4M | return ranges::empty(derived()) |
6086 | 22.4M | ? nullptr |
6087 | 22.4M | : std::addressof(*ranges::begin(derived())); |
6088 | 22.4M | } auto nano::ranges::view_interface<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::data<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>, void>() Line | Count | Source | 6084 | 18.3M | { | 6085 | 18.3M | return ranges::empty(derived()) | 6086 | 18.3M | ? nullptr | 6087 | 18.3M | : std::addressof(*ranges::begin(derived())); | 6088 | 18.3M | } |
auto nano::ranges::view_interface<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::data<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>, void>() Line | Count | Source | 6084 | 4.09M | { | 6085 | 4.09M | return ranges::empty(derived()) | 6086 | 4.09M | ? nullptr | 6087 | 4.09M | : std::addressof(*ranges::begin(derived())); | 6088 | 4.09M | } |
|
6089 | | |
6090 | | template <typename R = D, |
6091 | | typename = std::enable_if_t< |
6092 | | range<const R> && contiguous_iterator<iterator_t<const R>>>> |
6093 | | constexpr auto data() const |
6094 | 17.0M | { |
6095 | 17.0M | return ranges::empty(derived()) |
6096 | 17.0M | ? nullptr |
6097 | 17.0M | : std::addressof(*ranges::begin(derived())); |
6098 | 17.0M | } auto nano::ranges::view_interface<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::data<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>, void>() const Line | Count | Source | 6094 | 11.7M | { | 6095 | 11.7M | return ranges::empty(derived()) | 6096 | 11.7M | ? nullptr | 6097 | 11.7M | : std::addressof(*ranges::begin(derived())); | 6098 | 11.7M | } |
auto nano::ranges::view_interface<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::data<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>, void>() const Line | Count | Source | 6094 | 5.31M | { | 6095 | 5.31M | return ranges::empty(derived()) | 6096 | 5.31M | ? nullptr | 6097 | 5.31M | : std::addressof(*ranges::begin(derived())); | 6098 | 5.31M | } |
|
6099 | | |
6100 | | template <typename R = D, |
6101 | | typename = std::enable_if_t< |
6102 | | forward_range<R> && |
6103 | | sized_sentinel_for<sentinel_t<R>, iterator_t<R>>>> |
6104 | | constexpr auto size() |
6105 | | { |
6106 | | return ranges::end(derived()) - ranges::begin(derived()); |
6107 | | } |
6108 | | |
6109 | | template <typename R = D, |
6110 | | typename = std::enable_if_t< |
6111 | | forward_range<const R> && |
6112 | | sized_sentinel_for<sentinel_t<const R>, iterator_t<const R>>>> |
6113 | | constexpr auto size() const |
6114 | | { |
6115 | | return ranges::end(derived()) - ranges::begin(derived()); |
6116 | | } |
6117 | | |
6118 | | template <typename R = D, typename = std::enable_if_t<forward_range<R>>> |
6119 | | constexpr decltype(auto) front() |
6120 | | { |
6121 | | return *ranges::begin(derived()); |
6122 | | } |
6123 | | |
6124 | | template <typename R = D, |
6125 | | typename = std::enable_if_t<forward_range<const R>>> |
6126 | | constexpr decltype(auto) front() const |
6127 | | { |
6128 | | return *ranges::begin(derived()); |
6129 | | } |
6130 | | |
6131 | | template < |
6132 | | typename R = D, |
6133 | | typename = std::enable_if_t<bidirectional_range<R> && common_range<R>>> |
6134 | | constexpr decltype(auto) back() |
6135 | | { |
6136 | | return *ranges::prev(ranges::end(derived())); |
6137 | | } |
6138 | | |
6139 | | template <typename R = D, |
6140 | | typename = std::enable_if_t<bidirectional_range<const R> && |
6141 | | common_range<const R>>> |
6142 | | constexpr decltype(auto) back() const |
6143 | | { |
6144 | | return *ranges::prev(ranges::end(derived())); |
6145 | | } |
6146 | | |
6147 | | template <typename R = D, |
6148 | | typename = std::enable_if_t<random_access_range<R>>> |
6149 | | constexpr decltype(auto) operator[](iter_difference_t<iterator_t<R>> n) |
6150 | | { |
6151 | | return ranges::begin(derived())[n]; |
6152 | | } |
6153 | | |
6154 | | template <typename R = D, |
6155 | | typename = std::enable_if_t<random_access_range<const R>>> |
6156 | | constexpr decltype(auto) operator[]( |
6157 | | iter_difference_t<iterator_t<const R>> n) const |
6158 | | { |
6159 | | return ranges::begin(derived())[n]; |
6160 | | } |
6161 | | }; |
6162 | | |
6163 | | NANO_END_NAMESPACE |
6164 | | |
6165 | | #endif |
6166 | | |
6167 | | NANO_BEGIN_NAMESPACE |
6168 | | |
6169 | | // [ranges.subrange] |
6170 | | |
6171 | | enum class subrange_kind : bool { unsized, sized }; |
6172 | | |
6173 | | namespace detail { |
6174 | | |
6175 | | template <typename I, typename S, bool = sized_sentinel_for<S, I>> |
6176 | | struct default_subrange_kind { |
6177 | | static constexpr subrange_kind kind = subrange_kind::unsized; |
6178 | | }; |
6179 | | |
6180 | | template <typename I, typename S> |
6181 | | struct default_subrange_kind<I, S, true> { |
6182 | | static constexpr subrange_kind kind = subrange_kind::sized; |
6183 | | }; |
6184 | | |
6185 | | } // namespace detail |
6186 | | |
6187 | | namespace subrange_ { |
6188 | | |
6189 | | template <typename I, |
6190 | | typename S = I, |
6191 | | subrange_kind = detail::default_subrange_kind<I, S>::kind> |
6192 | | class subrange; |
6193 | | |
6194 | | } |
6195 | | |
6196 | | using subrange_::subrange; |
6197 | | |
6198 | | namespace detail { |
6199 | | |
6200 | | struct convertible_to_non_slicing_concept { |
6201 | | template <typename, typename> |
6202 | | static auto test(long) -> std::false_type; |
6203 | | |
6204 | | template <typename From, typename To> |
6205 | | static auto test(int) -> std::enable_if_t< |
6206 | | convertible_to<From, To> && |
6207 | | !(std::is_pointer_v<std::decay_t<From>> && |
6208 | | std::is_pointer_v<std::decay_t<To>> && |
6209 | | not_same_as<std::remove_pointer_t<std::decay_t<From>>, |
6210 | | std::remove_pointer_t<std::decay_t<To>>>), |
6211 | | std::true_type>; |
6212 | | }; |
6213 | | |
6214 | | template <typename From, typename To> |
6215 | | NANO_CONCEPT convertible_to_non_slicing = |
6216 | | decltype(convertible_to_non_slicing_concept::test<From, To>(0))::value; |
6217 | | |
6218 | | struct pair_like_concept { |
6219 | | template <typename> |
6220 | | static auto test(long) -> std::false_type; |
6221 | | |
6222 | | template <typename T, |
6223 | | typename = typename std::tuple_size<T>::type, |
6224 | | typename = |
6225 | | std::enable_if_t<detail::requires_<pair_like_concept, T>>> |
6226 | | static auto test(int) -> std::true_type; |
6227 | | |
6228 | | template <typename T> |
6229 | | auto requires_(T t) |
6230 | | -> decltype(requires_expr<derived_from< |
6231 | | std::tuple_size<T>, |
6232 | | std::integral_constant<std::size_t, 2>>>{}, |
6233 | | std::declval< |
6234 | | std::tuple_element_t<0, std::remove_const_t<T>>>(), |
6235 | | std::declval< |
6236 | | std::tuple_element_t<1, std::remove_const_t<T>>>(), |
6237 | | requires_expr< |
6238 | | convertible_to<decltype(std::get<0>(t)), |
6239 | | const std::tuple_element<0, T>&>>{}, |
6240 | | requires_expr< |
6241 | | convertible_to<decltype(std::get<1>(t)), |
6242 | | const std::tuple_element<1, T>&>>{}); |
6243 | | }; |
6244 | | |
6245 | | template <typename T> |
6246 | | NANO_CONCEPT pair_like = !std::is_reference_v<T> && |
6247 | | decltype(pair_like_concept::test<T>(0))::value; |
6248 | | |
6249 | | struct pair_like_convertible_from_concept { |
6250 | | template <typename, typename, typename> |
6251 | | static auto test(long) -> std::false_type; |
6252 | | |
6253 | | template <typename T, |
6254 | | typename U, |
6255 | | typename V, |
6256 | | std::enable_if_t<!range<T>, int> = 0, |
6257 | | std::enable_if_t<pair_like<T>, int> = 0, |
6258 | | std::enable_if_t<constructible_from<T, U, V>, int> = 0, |
6259 | | std::enable_if_t< |
6260 | | convertible_to_non_slicing<U, std::tuple_element<0, T>>, |
6261 | | int> = 0, |
6262 | | std::enable_if_t<convertible_to<V, std::tuple_element<1, T>>, |
6263 | | int> = 0> |
6264 | | static auto test(int) -> std::true_type; |
6265 | | }; |
6266 | | |
6267 | | template <typename T, typename U, typename V> |
6268 | | NANO_CONCEPT pair_like_convertible_from = |
6269 | | decltype(pair_like_convertible_from_concept::test<T, U, V>(0))::value; |
6270 | | |
6271 | | struct iterator_sentinel_pair_concept { |
6272 | | template <typename T> |
6273 | | static auto test(long) -> std::false_type; |
6274 | | |
6275 | | template <typename T> |
6276 | | static auto test(int) |
6277 | | -> std::enable_if_t<!range<T> && pair_like<T> && |
6278 | | sentinel_for<std::tuple_element_t<1, T>, |
6279 | | std::tuple_element_t<0, T>>, |
6280 | | std::true_type>; |
6281 | | }; |
6282 | | |
6283 | | template <typename T> |
6284 | | NANO_CONCEPT iterator_sentinel_pair = |
6285 | | decltype(iterator_sentinel_pair_concept::test<T>(0))::value; |
6286 | | |
6287 | | template <typename I, typename S, bool StoreSize = false> |
6288 | | struct subrange_data { |
6289 | | constexpr subrange_data() = default; |
6290 | | |
6291 | | constexpr subrange_data(I&& begin, S&& end) |
6292 | | : begin_(std::move(begin)), end_(std::move(end)) |
6293 | 101M | { |
6294 | 101M | } nano::ranges::detail::subrange_data<char const*, char const*, false>::subrange_data(char const*&&, char const*&&) Line | Count | Source | 6293 | 49.5M | { | 6294 | 49.5M | } |
nano::ranges::detail::subrange_data<wchar_t const*, wchar_t const*, false>::subrange_data(wchar_t const*&&, wchar_t const*&&) Line | Count | Source | 6293 | 44.5M | { | 6294 | 44.5M | } |
nano::ranges::detail::subrange_data<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, false>::subrange_data(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&&, nano::ranges::default_sentinel_t&&) Line | Count | Source | 6293 | 1.86M | { | 6294 | 1.86M | } |
nano::ranges::detail::subrange_data<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator, false>::subrange_data(scn::v2::detail::basic_scan_buffer<char>::forward_iterator&&, scn::v2::detail::basic_scan_buffer<char>::forward_iterator&&) Line | Count | Source | 6293 | 50.2k | { | 6294 | 50.2k | } |
nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>&&) Line | Count | Source | 6293 | 42.8k | { | 6294 | 42.8k | } |
nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&&, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>&&) Line | Count | Source | 6293 | 51.6k | { | 6294 | 51.6k | } |
Unexecuted instantiation: nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>&&) nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&&, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>&&) Line | Count | Source | 6293 | 1.40k | { | 6294 | 1.40k | } |
nano::ranges::detail::subrange_data<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, false>::subrange_data(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&&, nano::ranges::default_sentinel_t&&) Line | Count | Source | 6293 | 3.80M | { | 6294 | 3.80M | } |
nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>&&) Line | Count | Source | 6293 | 23.5k | { | 6294 | 23.5k | } |
nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&&, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>&&) Line | Count | Source | 6293 | 31.9k | { | 6294 | 31.9k | } |
nano::ranges::detail::subrange_data<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, false>::subrange_data(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&&, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator&&) Line | Count | Source | 6293 | 485k | { | 6294 | 485k | } |
Unexecuted instantiation: nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&&, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>&&) nano::ranges::detail::subrange_data<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, false>::subrange_data(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&&, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>&&) Line | Count | Source | 6293 | 4.62k | { | 6294 | 4.62k | } |
nano::ranges::detail::subrange_data<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, false>::subrange_data(std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>&&, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>&&) Line | Count | Source | 6293 | 381k | { | 6294 | 381k | } |
nano::ranges::detail::subrange_data<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, false>::subrange_data(std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>&&, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>&&) Line | Count | Source | 6293 | 736k | { | 6294 | 736k | } |
|
6295 | | |
6296 | | constexpr subrange_data(I&& begin, |
6297 | | S&& end, |
6298 | | iter_difference_t<I> /*unused*/) |
6299 | | : begin_(std::move(begin)), end_(std::move(end)) |
6300 | | { |
6301 | | } |
6302 | | |
6303 | | I begin_{}; |
6304 | | S end_{}; |
6305 | | }; |
6306 | | |
6307 | | template <typename I, typename S> |
6308 | | struct subrange_data<I, S, true> { |
6309 | | constexpr subrange_data() = default; |
6310 | | |
6311 | | constexpr subrange_data(I&& begin, S&& end, iter_difference_t<I> size) |
6312 | | : begin_(std::move(begin)), end_(std::move(end)), size_(size) |
6313 | | { |
6314 | | } |
6315 | | |
6316 | | I begin_{}; |
6317 | | S end_{}; |
6318 | | iter_difference_t<I> size_ = 0; |
6319 | | }; |
6320 | | |
6321 | | // MSVC gets confused if enable_if conditions in template param lists are |
6322 | | // too complex, so give it some help by calculating the constraints in a |
6323 | | // helper variable |
6324 | | template <typename R, typename I, typename S, subrange_kind K> |
6325 | | auto subrange_range_constructor_constraint_helper_fn(long) |
6326 | | -> std::false_type; |
6327 | | |
6328 | | template <typename R, typename I, typename S, subrange_kind K> |
6329 | | auto subrange_range_constructor_constraint_helper_fn(int) |
6330 | | -> std::enable_if_t<borrowed_range<R> && |
6331 | | convertible_to_non_slicing<iterator_t<R>, I> && |
6332 | | convertible_to<sentinel_t<R>, S>, |
6333 | | std::true_type>; |
6334 | | |
6335 | | template <typename R, typename I, typename S, subrange_kind K> |
6336 | | constexpr bool subrange_range_constructor_constraint_helper = |
6337 | | decltype(subrange_range_constructor_constraint_helper_fn<R, I, S, K>( |
6338 | | 0))::value; |
6339 | | |
6340 | | template <typename R> |
6341 | | constexpr subrange_kind subrange_deduction_guide_helper() |
6342 | 0 | { |
6343 | 0 | return (sized_range<R> || |
6344 | 0 | sized_sentinel_for<sentinel_t<R>, iterator_t<R>>) |
6345 | 0 | ? subrange_kind::sized |
6346 | 0 | : subrange_kind::unsized; |
6347 | 0 | } |
6348 | | |
6349 | | } // namespace detail |
6350 | | |
6351 | | namespace subrange_ { |
6352 | | |
6353 | | template <typename I, typename S, subrange_kind K> |
6354 | | class subrange : public view_interface<subrange<I, S, K>> { |
6355 | | static_assert(input_or_output_iterator<I>); |
6356 | | static_assert(sentinel_for<S, I>); |
6357 | | static_assert(K == subrange_kind::sized || !sized_sentinel_for<S, I>, |
6358 | | ""); |
6359 | | |
6360 | | private: |
6361 | | static constexpr bool StoreSize = |
6362 | | K == subrange_kind::sized && !sized_sentinel_for<S, I>; |
6363 | | |
6364 | | detail::subrange_data<I, S, StoreSize> data_{}; |
6365 | | |
6366 | | public: |
6367 | | subrange() = default; |
6368 | | |
6369 | | template <typename II, |
6370 | | bool SS = StoreSize, |
6371 | | typename = std::enable_if_t< |
6372 | | detail::convertible_to_non_slicing<II, I> && !SS>> |
6373 | | constexpr subrange(II i, S s) : data_{std::move(i), std::move(s)} |
6374 | 101M | { |
6375 | 101M | } nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>::subrange<char const*, false, void>(char const*, char const*) Line | Count | Source | 6374 | 49.5M | { | 6375 | 49.5M | } |
nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>::subrange<wchar_t const*, false, void>(wchar_t const*, wchar_t const*) Line | Count | Source | 6374 | 44.5M | { | 6375 | 44.5M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, false, void>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t) Line | Count | Source | 6374 | 1.86M | { | 6375 | 1.86M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator, (nano::ranges::subrange_kind)0>::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, false, void>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator) Line | Count | Source | 6374 | 50.2k | { | 6375 | 50.2k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) Line | Count | Source | 6374 | 42.8k | { | 6375 | 42.8k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>) Line | Count | Source | 6374 | 51.6k | { | 6375 | 51.6k | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>) Line | Count | Source | 6374 | 1.40k | { | 6375 | 1.40k | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, false, void>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t) Line | Count | Source | 6374 | 3.80M | { | 6375 | 3.80M | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>) Line | Count | Source | 6374 | 23.5k | { | 6375 | 23.5k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>) Line | Count | Source | 6374 | 31.9k | { | 6375 | 31.9k | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, (nano::ranges::subrange_kind)0>::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, false, void>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator) Line | Count | Source | 6374 | 485k | { | 6375 | 485k | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>) nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, false, void>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>) Line | Count | Source | 6374 | 4.62k | { | 6375 | 4.62k | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, (nano::ranges::subrange_kind)1>::subrange<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, false, void>(std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>) Line | Count | Source | 6374 | 381k | { | 6375 | 381k | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, (nano::ranges::subrange_kind)1>::subrange<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, false, void>(std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>) Line | Count | Source | 6374 | 736k | { | 6375 | 736k | } |
|
6376 | | |
6377 | | template <typename II, |
6378 | | subrange_kind KK = K, |
6379 | | typename = std::enable_if_t< |
6380 | | detail::convertible_to_non_slicing<II, I> && |
6381 | | KK == subrange_kind::sized>> |
6382 | | constexpr subrange(II i, S s, iter_difference_t<I> n) |
6383 | | : data_{std::move(i), std::move(s), n} |
6384 | | { |
6385 | | } |
6386 | | |
6387 | | template <typename R, |
6388 | | bool SS = StoreSize, |
6389 | | std::enable_if_t<detail::not_same_as<R, subrange>, int> = 0, |
6390 | | std::enable_if_t< |
6391 | | detail::subrange_range_constructor_constraint_helper<R, |
6392 | | I, |
6393 | | S, |
6394 | | K> && |
6395 | | SS && sized_range<R>, |
6396 | | int> = 0> |
6397 | | constexpr subrange(R&& r) |
6398 | | : subrange(ranges::begin(r), ranges::end(r), ranges::size(r)) |
6399 | | { |
6400 | | } |
6401 | | |
6402 | | template <typename R, |
6403 | | bool SS = StoreSize, |
6404 | | std::enable_if_t<detail::not_same_as<R, subrange>, int> = 0, |
6405 | | std::enable_if_t< |
6406 | | detail::subrange_range_constructor_constraint_helper<R, |
6407 | | I, |
6408 | | S, |
6409 | | K> && |
6410 | | !SS, |
6411 | | int> = 0> |
6412 | | constexpr subrange(R&& r) : subrange(ranges::begin(r), ranges::end(r)) |
6413 | | { |
6414 | | } |
6415 | | |
6416 | | template < |
6417 | | typename R, |
6418 | | subrange_kind KK = K, |
6419 | | std::enable_if_t< |
6420 | | borrowed_range<R> && |
6421 | | detail::convertible_to_non_slicing<iterator_t<R>, I> && |
6422 | | convertible_to<sentinel_t<R>, S> && |
6423 | | KK == subrange_kind::sized, |
6424 | | int> = 0> |
6425 | | constexpr subrange(R&& r, iter_difference_t<I> n) |
6426 | | : subrange(ranges::begin(r), ranges::end(r), n) |
6427 | | { |
6428 | | } |
6429 | | |
6430 | | template < |
6431 | | typename PairLike_, |
6432 | | std::enable_if_t<detail::not_same_as<PairLike_, subrange>, int> = 0, |
6433 | | std::enable_if_t<detail::pair_like_convertible_from<PairLike_, |
6434 | | const I&, |
6435 | | const S&>, |
6436 | | int> = 0> |
6437 | | constexpr operator PairLike_() const |
6438 | | { |
6439 | | return PairLike_(begin(), end()); |
6440 | | } |
6441 | | |
6442 | | constexpr I begin() const |
6443 | 265M | { |
6444 | 265M | return data_.begin_; |
6445 | 265M | } nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 7.77M | { | 6444 | 7.77M | return data_.begin_; | 6445 | 7.77M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 15.7M | { | 6444 | 15.7M | return data_.begin_; | 6445 | 15.7M | } |
nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>::begin() const Line | Count | Source | 6443 | 121M | { | 6444 | 121M | return data_.begin_; | 6445 | 121M | } |
nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>::begin() const Line | Count | Source | 6443 | 117M | { | 6444 | 117M | return data_.begin_; | 6445 | 117M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 143k | { | 6444 | 143k | return data_.begin_; | 6445 | 143k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 131k | { | 6444 | 131k | return data_.begin_; | 6445 | 131k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 51.6k | { | 6444 | 51.6k | return data_.begin_; | 6445 | 51.6k | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::begin() const nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 1.40k | { | 6444 | 1.40k | return data_.begin_; | 6445 | 1.40k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 73.0k | { | 6444 | 73.0k | return data_.begin_; | 6445 | 73.0k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 31.9k | { | 6444 | 31.9k | return data_.begin_; | 6445 | 31.9k | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 1.38M | { | 6444 | 1.38M | return data_.begin_; | 6445 | 1.38M | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::begin() const nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::begin() const Line | Count | Source | 6443 | 4.62k | { | 6444 | 4.62k | return data_.begin_; | 6445 | 4.62k | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, (nano::ranges::subrange_kind)1>::begin() const Line | Count | Source | 6443 | 383k | { | 6444 | 383k | return data_.begin_; | 6445 | 383k | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, (nano::ranges::subrange_kind)1>::begin() const Line | Count | Source | 6443 | 770k | { | 6444 | 770k | return data_.begin_; | 6445 | 770k | } |
|
6446 | | |
6447 | | constexpr S end() const |
6448 | 478M | { |
6449 | 478M | return data_.end_; |
6450 | 478M | } nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>::end() const Line | Count | Source | 6448 | 69.9M | { | 6449 | 69.9M | return data_.end_; | 6450 | 69.9M | } |
nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>::end() const Line | Count | Source | 6448 | 205M | { | 6449 | 205M | return data_.end_; | 6450 | 205M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 3.16M | { | 6449 | 3.16M | return data_.end_; | 6450 | 3.16M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, scn::v2::detail::basic_scan_buffer<char>::forward_iterator, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 143k | { | 6449 | 143k | return data_.end_; | 6450 | 143k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 167k | { | 6449 | 167k | return data_.end_; | 6450 | 167k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 51.6k | { | 6449 | 51.6k | return data_.end_; | 6450 | 51.6k | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::end() const nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 1.40k | { | 6449 | 1.40k | return data_.end_; | 6450 | 1.40k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 48.1k | { | 6449 | 48.1k | return data_.end_; | 6450 | 48.1k | } |
nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 31.9k | { | 6449 | 31.9k | return data_.end_; | 6450 | 31.9k | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 6.83M | { | 6449 | 6.83M | return data_.end_; | 6450 | 6.83M | } |
nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 1.38M | { | 6449 | 1.38M | return data_.end_; | 6450 | 1.38M | } |
Unexecuted instantiation: nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, (nano::ranges::subrange_kind)0>::end() const nano::ranges::subrange_::subrange<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, (nano::ranges::subrange_kind)0>::end() const Line | Count | Source | 6448 | 4.62k | { | 6449 | 4.62k | return data_.end_; | 6450 | 4.62k | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, std::__1::__deque_iterator<char, char const*, char const&, char const* const*, long, 4096l>, (nano::ranges::subrange_kind)1>::end() const Line | Count | Source | 6448 | 72.5M | { | 6449 | 72.5M | return data_.end_; | 6450 | 72.5M | } |
nano::ranges::subrange_::subrange<std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, std::__1::__deque_iterator<wchar_t, wchar_t const*, wchar_t const&, wchar_t const* const*, long, 1024l>, (nano::ranges::subrange_kind)1>::end() const Line | Count | Source | 6448 | 119M | { | 6449 | 119M | return data_.end_; | 6450 | 119M | } |
|
6451 | | |
6452 | | [[nodiscard]] constexpr bool empty() const |
6453 | 39.4M | { |
6454 | 39.4M | return data_.begin_ == data_.end_; |
6455 | 39.4M | } nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>::empty() const Line | Count | Source | 6453 | 30.0M | { | 6454 | 30.0M | return data_.begin_ == data_.end_; | 6455 | 30.0M | } |
nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>::empty() const Line | Count | Source | 6453 | 9.41M | { | 6454 | 9.41M | return data_.begin_ == data_.end_; | 6455 | 9.41M | } |
|
6456 | | |
6457 | | template <subrange_kind KK = K> |
6458 | | constexpr auto size() const |
6459 | | -> std::enable_if_t<KK == subrange_kind::sized, |
6460 | | iter_difference_t<I>> |
6461 | 51.0M | { |
6462 | 51.0M | if constexpr (StoreSize) { |
6463 | 51.0M | return data_.size_; |
6464 | 51.0M | } |
6465 | 51.0M | else { |
6466 | 51.0M | return data_.end_ - data_.begin_; |
6467 | 51.0M | } |
6468 | 51.0M | } std::__1::enable_if<((nano::ranges::subrange_kind)1)==((nano::ranges::subrange_kind)1), long>::type nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1>::size<(nano::ranges::subrange_kind)1>() const Line | Count | Source | 6461 | 30.2M | { | 6462 | 30.2M | if constexpr (StoreSize) { | 6463 | 30.2M | return data_.size_; | 6464 | 30.2M | } | 6465 | 30.2M | else { | 6466 | 30.2M | return data_.end_ - data_.begin_; | 6467 | 30.2M | } | 6468 | 30.2M | } |
std::__1::enable_if<((nano::ranges::subrange_kind)1)==((nano::ranges::subrange_kind)1), long>::type nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1>::size<(nano::ranges::subrange_kind)1>() const Line | Count | Source | 6461 | 20.8M | { | 6462 | 20.8M | if constexpr (StoreSize) { | 6463 | 20.8M | return data_.size_; | 6464 | 20.8M | } | 6465 | 20.8M | else { | 6466 | 20.8M | return data_.end_ - data_.begin_; | 6467 | 20.8M | } | 6468 | 20.8M | } |
|
6469 | | |
6470 | | [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const |
6471 | | { |
6472 | | auto tmp = *this; |
6473 | | tmp.advance(n); |
6474 | | return tmp; |
6475 | | } |
6476 | | |
6477 | | template <typename II = I> |
6478 | | [[nodiscard]] constexpr auto prev(iter_difference_t<I> n = 1) const |
6479 | | -> std::enable_if_t<bidirectional_iterator<II>, subrange> |
6480 | | { |
6481 | | auto tmp = *this; |
6482 | | tmp.advance(-n); |
6483 | | return tmp; |
6484 | | } |
6485 | | |
6486 | | constexpr subrange& advance(iter_difference_t<I> n) |
6487 | | { |
6488 | | if constexpr (StoreSize) { |
6489 | | data_.size_ -= n - ranges::advance(data_.begin_, n, data_.end_); |
6490 | | } |
6491 | | else { |
6492 | | ranges::advance(data_.begin_, n, data_.end_); |
6493 | | } |
6494 | | return *this; |
6495 | | } |
6496 | | }; |
6497 | | |
6498 | | template < |
6499 | | typename I, |
6500 | | typename S, |
6501 | | std::enable_if_t<input_or_output_iterator<I> && sentinel_for<S, I>, |
6502 | | int> = 0> |
6503 | | subrange(I, S) -> subrange<I, S>; |
6504 | | |
6505 | | template < |
6506 | | typename I, |
6507 | | typename S, |
6508 | | std::enable_if_t<input_or_output_iterator<I> && sentinel_for<S, I>, |
6509 | | int> = 0> |
6510 | | subrange(I, S, iter_difference_t<I>) |
6511 | | -> subrange<I, S, subrange_kind::sized>; |
6512 | | |
6513 | | template <typename P, |
6514 | | std::enable_if_t<detail::iterator_sentinel_pair<P>, int> = 0> |
6515 | | subrange(P) |
6516 | | -> subrange<std::tuple_element_t<0, P>, std::tuple_element_t<1, P>>; |
6517 | | |
6518 | | template <typename P, |
6519 | | std::enable_if_t<detail::iterator_sentinel_pair<P>, int> = 0> |
6520 | | subrange(P, iter_difference_t<std::tuple_element_t<0, P>>) |
6521 | | -> subrange<std::tuple_element_t<0, P>, |
6522 | | std::tuple_element_t<1, P>, |
6523 | | subrange_kind::sized>; |
6524 | | |
6525 | | template <typename R, std::enable_if_t<borrowed_range<R>, int> = 0> |
6526 | | subrange(R&&) -> subrange<iterator_t<R>, |
6527 | | sentinel_t<R>, |
6528 | | detail::subrange_deduction_guide_helper<R>()>; |
6529 | | |
6530 | | template <typename R, std::enable_if_t<borrowed_range<R>, int> = 0> |
6531 | | subrange(R&&, iter_difference_t<iterator_t<R>>) |
6532 | | -> subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>; |
6533 | | |
6534 | | } // namespace subrange_ |
6535 | | |
6536 | | template <typename I, typename S, subrange_kind K> |
6537 | | inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true; |
6538 | | |
6539 | | template <std::size_t N, |
6540 | | typename I, |
6541 | | typename S, |
6542 | | subrange_kind K, |
6543 | | std::enable_if_t<(N < 2), int> = 0> |
6544 | | constexpr auto get(const subrange<I, S, K>& r) |
6545 | | { |
6546 | | if constexpr (N == 0) { |
6547 | | return r.begin(); |
6548 | | } |
6549 | | else { |
6550 | | return r.end(); |
6551 | | } |
6552 | | } |
6553 | | |
6554 | | template <typename R> |
6555 | | using borrowed_subrange_t = |
6556 | | detail::conditional_t<borrowed_range<R>, subrange<iterator_t<R>>, dangling>; |
6557 | | |
6558 | | NANO_END_NAMESPACE |
6559 | | |
6560 | | namespace std { |
6561 | | |
6562 | | template <typename I, typename S, ::nano::subrange_kind K> |
6563 | | class tuple_size<::nano::subrange<I, S, K>> |
6564 | | : public integral_constant<size_t, 2> {}; |
6565 | | |
6566 | | template <typename I, typename S, ::nano::subrange_kind K> |
6567 | | class tuple_element<0, ::nano::subrange<I, S, K>> { |
6568 | | public: |
6569 | | using type = I; |
6570 | | }; |
6571 | | |
6572 | | template <typename I, typename S, ::nano::subrange_kind K> |
6573 | | class tuple_element<1, ::nano::subrange<I, S, K>> { |
6574 | | public: |
6575 | | using type = S; |
6576 | | }; |
6577 | | |
6578 | | using ::nano::ranges::get; |
6579 | | |
6580 | | } // namespace std |
6581 | | |
6582 | | #endif |
6583 | | |
6584 | | NANO_BEGIN_NAMESPACE |
6585 | | |
6586 | | namespace detail { |
6587 | | |
6588 | | struct equal_range_fn { |
6589 | | private: |
6590 | | template <typename I, |
6591 | | typename S, |
6592 | | typename T, |
6593 | | typename Comp, |
6594 | | typename Proj> |
6595 | | static constexpr subrange<I> impl(I first, |
6596 | | S last, |
6597 | | const T& value, |
6598 | | Comp& comp, |
6599 | | Proj& proj) |
6600 | | { |
6601 | | return {lower_bound_fn::impl(first, last, value, comp, proj), |
6602 | | upper_bound_fn::impl(first, last, value, comp, proj)}; |
6603 | | } |
6604 | | |
6605 | | public: |
6606 | | template <typename I, |
6607 | | typename S, |
6608 | | typename T, |
6609 | | typename Comp = ranges::less, |
6610 | | typename Proj = identity> |
6611 | | std::enable_if_t< |
6612 | | forward_iterator<I> && sentinel_for<S, I> && |
6613 | | indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>, |
6614 | | subrange<I>> constexpr |
6615 | | operator()(I first, |
6616 | | S last, |
6617 | | const T& value, |
6618 | | Comp comp = Comp{}, |
6619 | | Proj proj = Proj{}) const |
6620 | | { |
6621 | | return equal_range_fn::impl(std::move(first), std::move(last), |
6622 | | value, comp, proj); |
6623 | | } |
6624 | | |
6625 | | template <typename Rng, |
6626 | | typename T, |
6627 | | typename Comp = ranges::less, |
6628 | | typename Proj = identity> |
6629 | | std::enable_if_t< |
6630 | | forward_range<Rng> && |
6631 | | indirect_strict_weak_order<Comp, |
6632 | | const T*, |
6633 | | projected<iterator_t<Rng>, Proj>>, |
6634 | | borrowed_subrange_t<Rng>> constexpr |
6635 | | operator()(Rng&& rng, |
6636 | | const T& value, |
6637 | | Comp comp = Comp{}, |
6638 | | Proj proj = Proj{}) const |
6639 | | { |
6640 | | return equal_range_fn::impl(nano::begin(rng), nano::end(rng), value, |
6641 | | comp, proj); |
6642 | | } |
6643 | | }; |
6644 | | |
6645 | | } // namespace detail |
6646 | | |
6647 | | NANO_INLINE_VAR(detail::equal_range_fn, equal_range) |
6648 | | |
6649 | | NANO_END_NAMESPACE |
6650 | | |
6651 | | #endif |
6652 | | |
6653 | | // nanorange/algorithm/fill.hpp |
6654 | | // |
6655 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6656 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
6657 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6658 | | |
6659 | | #ifndef NANORANGE_ALGORITHM_FILL_HPP_INCLUDED |
6660 | | #define NANORANGE_ALGORITHM_FILL_HPP_INCLUDED |
6661 | | |
6662 | | NANO_BEGIN_NAMESPACE |
6663 | | |
6664 | | namespace detail { |
6665 | | |
6666 | | struct fill_fn { |
6667 | | private: |
6668 | | template <typename T, typename O, typename S> |
6669 | | static constexpr O impl(O first, S last, const T& value) |
6670 | | { |
6671 | | while (first != last) { |
6672 | | *first = value; |
6673 | | ++first; |
6674 | | } |
6675 | | |
6676 | | return first; |
6677 | | } |
6678 | | |
6679 | | public: |
6680 | | template <typename T, typename O, typename S> |
6681 | | constexpr std:: |
6682 | | enable_if_t<output_iterator<O, const T&> && sentinel_for<S, O>, O> |
6683 | | operator()(O first, S last, const T& value) const |
6684 | | { |
6685 | | return fill_fn::impl(std::move(first), std::move(last), value); |
6686 | | } |
6687 | | |
6688 | | template <typename T, typename Rng> |
6689 | | constexpr std::enable_if_t<output_range<Rng, const T&>, |
6690 | | borrowed_iterator_t<Rng>> |
6691 | | operator()(Rng&& rng, const T& value) const |
6692 | | { |
6693 | | return fill_fn::impl(nano::begin(rng), nano::end(rng), value); |
6694 | | } |
6695 | | }; |
6696 | | |
6697 | | } // namespace detail |
6698 | | |
6699 | | NANO_INLINE_VAR(detail::fill_fn, fill) |
6700 | | |
6701 | | NANO_END_NAMESPACE |
6702 | | |
6703 | | #endif |
6704 | | |
6705 | | // nanorange/algorithm/fill_n.hpp |
6706 | | // |
6707 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6708 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
6709 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6710 | | |
6711 | | #ifndef NANORANGE_ALGORITHM_FILL_N_HPP_INCLUDED |
6712 | | #define NANORANGE_ALGORITHM_FILL_N_HPP_INCLUDED |
6713 | | |
6714 | | NANO_BEGIN_NAMESPACE |
6715 | | |
6716 | | namespace detail { |
6717 | | |
6718 | | struct fill_n_fn { |
6719 | | template <typename T, typename O> |
6720 | | constexpr std::enable_if_t<output_iterator<O, const T&>, O> |
6721 | | operator()(O first, iter_difference_t<O> n, const T& value) const |
6722 | | { |
6723 | | for (iter_difference_t<O> i{0}; i < n; ++i, ++first) { |
6724 | | *first = value; |
6725 | | } |
6726 | | return first; |
6727 | | } |
6728 | | }; |
6729 | | |
6730 | | } // namespace detail |
6731 | | |
6732 | | NANO_INLINE_VAR(detail::fill_n_fn, fill_n) |
6733 | | |
6734 | | NANO_END_NAMESPACE |
6735 | | |
6736 | | #endif |
6737 | | |
6738 | | // nanorange/algorithm/find.hpp |
6739 | | // |
6740 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6741 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
6742 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6743 | | |
6744 | | #ifndef NANORANGE_ALGORITHM_FIND_HPP_INCLUDED |
6745 | | #define NANORANGE_ALGORITHM_FIND_HPP_INCLUDED |
6746 | | |
6747 | | NANO_BEGIN_NAMESPACE |
6748 | | |
6749 | | // [ranges.alg.find] |
6750 | | |
6751 | | namespace detail { |
6752 | | |
6753 | | struct find_if_fn { |
6754 | | private: |
6755 | | friend struct find_fn; |
6756 | | friend struct find_if_not_fn; |
6757 | | |
6758 | | template <typename I, typename S, typename Pred, typename Proj> |
6759 | | static constexpr I impl(I first, S last, Pred& pred, Proj& proj) |
6760 | 15.4M | { |
6761 | 77.7M | while (first != last) { |
6762 | 72.7M | if (nano::invoke(pred, nano::invoke(proj, *first))) { |
6763 | 10.4M | return first; |
6764 | 10.4M | } |
6765 | 62.3M | ++first; |
6766 | 62.3M | } |
6767 | 4.98M | return first; |
6768 | 15.4M | } char const* nano::ranges::detail::find_if_fn::impl<char const*, char const*, scn::v2::impl::function_ref<bool (char), bool (char)>, nano::ranges::identity>(char const*, char const*, scn::v2::impl::function_ref<bool (char), bool (char)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 1.28M | { | 6761 | 7.36M | while (first != last) { | 6762 | 7.35M | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 1.27M | return first; | 6764 | 1.27M | } | 6765 | 6.07M | ++first; | 6766 | 6.07M | } | 6767 | 10.8k | return first; | 6768 | 1.28M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10find_if_fn4implINSt3__111__wrap_iterIPcEES7_KZNKS1_7find_fnclIRNS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEcNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SH_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSJ_EEEENS1_16projected_helperISR_SM_vEEEEPKT0_EENSL_IX14borrowed_rangeISJ_EEE4typeISR_NS0_8danglingEEEE4typeEOSJ_RSW_SM_EUlRKSJ_E_SH_EESJ_SJ_SV_RSM_RT2_ scn::v2::detail::basic_scan_buffer<char>::forward_iterator nano::ranges::detail::find_if_fn::impl<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, scn::v2::impl::function_ref<bool (char), bool (char)>, nano::ranges::identity>(scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, scn::v2::impl::function_ref<bool (char), bool (char)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 270k | { | 6761 | 271k | while (first != last) { | 6762 | 271k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 270k | return first; | 6764 | 270k | } | 6765 | 1.40k | ++first; | 6766 | 1.40k | } | 6767 | 41 | return first; | 6768 | 270k | } |
scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*> nano::ranges::detail::find_if_fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::function_ref<bool (char), bool (char)>, nano::ranges::identity>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<char const*, char const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<char const*, char const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::function_ref<bool (char), bool (char)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 1.42k | { | 6761 | 7.53k | while (first != last) { | 6762 | 7.37k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 1.26k | return first; | 6764 | 1.26k | } | 6765 | 6.10k | ++first; | 6766 | 6.10k | } | 6767 | 156 | return first; | 6768 | 1.42k | } |
std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*> nano::ranges::detail::find_if_fn::impl<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, scn::v2::impl::character_set_reader_impl<char>::specs_helper::is_char_set_in_extra_literals(char32_t) const::{lambda(auto:1 const&)#1}, nano::ranges::identity>(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, scn::v2::impl::character_set_reader_impl<char>::specs_helper::is_char_set_in_extra_literals(char32_t) const::{lambda(auto:1 const&)#1}&, nano::ranges::identity&)Line | Count | Source | 6760 | 56.8k | { | 6761 | 1.04M | while (first != last) { | 6762 | 999k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 15.5k | return first; | 6764 | 15.5k | } | 6765 | 983k | ++first; | 6766 | 983k | } | 6767 | 41.2k | return first; | 6768 | 56.8k | } |
Unexecuted instantiation: scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t> nano::ranges::detail::find_if_fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::function_ref<bool (char), bool (char)>, nano::ranges::identity>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<char>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::function_ref<bool (char), bool (char)>&, nano::ranges::identity&) wchar_t const* nano::ranges::detail::find_if_fn::impl<wchar_t const*, wchar_t const*, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>, nano::ranges::identity>(wchar_t const*, wchar_t const*, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 1.14M | { | 6761 | 5.90M | while (first != last) { | 6762 | 5.88M | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 1.13M | return first; | 6764 | 1.13M | } | 6765 | 4.75M | ++first; | 6766 | 4.75M | } | 6767 | 11.2k | return first; | 6768 | 1.14M | } |
Unexecuted instantiation: _ZN4nano6ranges6detail10find_if_fn4implINSt3__111__wrap_iterIPwEES7_KZNKS1_7find_fnclIRNS4_12basic_stringIwNS4_11char_traitsIwEENS4_9allocatorIwEEEEwNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SH_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSJ_EEEENS1_16projected_helperISR_SM_vEEEEPKT0_EENSL_IX14borrowed_rangeISJ_EEE4typeISR_NS0_8danglingEEEE4typeEOSJ_RSW_SM_EUlRKSJ_E_SH_EESJ_SJ_SV_RSM_RT2_ scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*> nano::ranges::detail::find_if_fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>, nano::ranges::identity>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<wchar_t const*, wchar_t const*>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<wchar_t const*, wchar_t const*, (nano::ranges::subrange_kind)1> >::sentinel<true>, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 1.10k | { | 6761 | 2.85k | while (first != last) { | 6762 | 2.79k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 1.04k | return first; | 6764 | 1.04k | } | 6765 | 1.74k | ++first; | 6766 | 1.74k | } | 6767 | 60 | return first; | 6768 | 1.10k | } |
std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*> nano::ranges::detail::find_if_fn::impl<std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, scn::v2::impl::character_set_reader_impl<wchar_t>::specs_helper::is_char_set_in_extra_literals(char32_t) const::{lambda(auto:1 const&)#1}, nano::ranges::identity>(std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, std::__1::__wrap_iter<std::__1::pair<char32_t, char32_t> const*>, scn::v2::impl::character_set_reader_impl<wchar_t>::specs_helper::is_char_set_in_extra_literals(char32_t) const::{lambda(auto:1 const&)#1}&, nano::ranges::identity&)Line | Count | Source | 6760 | 55.7k | { | 6761 | 4.78M | while (first != last) { | 6762 | 4.77M | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 52.7k | return first; | 6764 | 52.7k | } | 6765 | 4.72M | ++first; | 6766 | 4.72M | } | 6767 | 2.97k | return first; | 6768 | 55.7k | } |
scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator nano::ranges::detail::find_if_fn::impl<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>, nano::ranges::identity>(scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>&, nano::ranges::identity&) Line | Count | Source | 6760 | 479k | { | 6761 | 484k | while (first != last) { | 6762 | 484k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 479k | return first; | 6764 | 479k | } | 6765 | 4.73k | ++first; | 6766 | 4.73k | } | 6767 | 43 | return first; | 6768 | 479k | } |
Unexecuted instantiation: scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t> nano::ranges::detail::find_if_fn::impl<scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>, nano::ranges::identity>(scn::v2::impl::counted_width_iterator_impl::counted_width_iterator<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t>, scn::v2::impl::take_width_view<nano::ranges::subrange_::subrange<scn::v2::detail::basic_scan_buffer<wchar_t>::forward_iterator, nano::ranges::default_sentinel_t, (nano::ranges::subrange_kind)0> >::sentinel<true>, scn::v2::impl::function_ref<bool (wchar_t), bool (wchar_t)>&, nano::ranges::identity&) find_whitespace.cpp:char const* nano::ranges::detail::find_if_fn::impl<char const*, char const*, scn::v2::impl::(anonymous namespace)::find_nondecimal_digit_simple_impl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0, nano::ranges::identity>(char const*, char const*, scn::v2::impl::(anonymous namespace)::find_nondecimal_digit_simple_impl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0&, nano::ranges::identity&) Line | Count | Source | 6760 | 178k | { | 6761 | 182k | while (first != last) { | 6762 | 182k | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 178k | return first; | 6764 | 178k | } | 6765 | 3.75k | ++first; | 6766 | 3.75k | } | 6767 | 16 | return first; | 6768 | 178k | } |
find_whitespace.cpp:char const* nano::ranges::detail::find_if_fn::impl<char const*, char const*, scn::v2::impl::find_classic_space_narrow_fast(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0, nano::ranges::identity>(char const*, char const*, scn::v2::impl::find_classic_space_narrow_fast(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0&, nano::ranges::identity&) Line | Count | Source | 6760 | 5.81M | { | 6761 | 45.3M | while (first != last) { | 6762 | 40.6M | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 1.06M | return first; | 6764 | 1.06M | } | 6765 | 39.5M | ++first; | 6766 | 39.5M | } | 6767 | 4.74M | return first; | 6768 | 5.81M | } |
find_whitespace.cpp:char const* nano::ranges::detail::find_if_fn::impl<char const*, char const*, scn::v2::impl::find_classic_nonspace_narrow_fast(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0, nano::ranges::identity>(char const*, char const*, scn::v2::impl::find_classic_nonspace_narrow_fast(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::$_0&, nano::ranges::identity&) Line | Count | Source | 6760 | 6.15M | { | 6761 | 12.3M | while (first != last) { | 6762 | 12.1M | if (nano::invoke(pred, nano::invoke(proj, *first))) { | 6763 | 5.98M | return first; | 6764 | 5.98M | } | 6765 | 6.20M | ++first; | 6766 | 6.20M | } | 6767 | 168k | return first; | 6768 | 6.15M | } |
|
6769 | | |
6770 | | public: |
6771 | | template <typename I, |
6772 | | typename S, |
6773 | | typename Proj = identity, |
6774 | | typename Pred> |
6775 | | constexpr std::enable_if_t< |
6776 | | input_iterator<I> && sentinel_for<S, I> && |
6777 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
6778 | | I> |
6779 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
6780 | | { |
6781 | | return find_if_fn::impl(std::move(first), std::move(last), pred, |
6782 | | proj); |
6783 | | } |
6784 | | |
6785 | | template <typename Rng, typename Proj = identity, typename Pred> |
6786 | | constexpr std::enable_if_t< |
6787 | | input_range<Rng> && |
6788 | | indirect_unary_predicate<Pred, |
6789 | | projected<iterator_t<Rng>, Proj>>, |
6790 | | borrowed_iterator_t<Rng>> |
6791 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
6792 | 15.4M | { |
6793 | 15.4M | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
6794 | 15.4M | proj); |
6795 | 15.4M | } _ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIPKcS7_LNS0_13subrange_kindE1EEENS0_8identityEN3scn2v24impl12function_refIFbcESG_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SB_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSK_EEEENS1_16projected_helperISS_SN_vEEEEEENSM_IX14borrowed_rangeISK_EEE4typeISS_NS0_8danglingEEEE4typeEOSK_SL_SN_ Line | Count | Source | 6792 | 1.28M | { | 6793 | 1.28M | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 1.28M | proj); | 6795 | 1.28M | } |
_ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEENS0_8identityENS7_4impl12function_refIFbcESJ_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SG_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSN_EEEENS1_16projected_helperISV_SQ_vEEEEEENSP_IX14borrowed_rangeISN_EEE4typeISV_NS0_8danglingEEEE4typeEOSN_SO_SQ_ Line | Count | Source | 6792 | 270k | { | 6793 | 270k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 270k | proj); | 6795 | 270k | } |
_ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKcSC_EENS8_15take_width_viewINS5_ISC_SC_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSF_0EEENS0_8identityENS8_12function_refIFbcESO_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SM_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSS_EEEENS1_16projected_helperIS10_SV_vEEEEEENSU_IX14borrowed_rangeISS_EEE4typeIS10_NS0_8danglingEEEE4typeEOSS_ST_SV_ Line | Count | Source | 6792 | 1.18k | { | 6793 | 1.18k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 1.18k | proj); | 6795 | 1.18k | } |
_ZNK4nano6ranges6detail10find_if_fnclIRKNSt3__16vectorINS4_4pairIDiDiEENS4_9allocatorIS7_EEEENS0_8identityEZNK3scn2v24impl25character_set_reader_implIcE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_EENS4_9enable_ifIXaa11input_rangeISK_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SD_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSK_EEEENS1_16projected_helperISW_SR_vEEEEEENSQ_IX14borrowed_rangeISK_EEE4typeISW_NS0_8danglingEEEE4typeEOSK_SP_SR_ Line | Count | Source | 6792 | 56.8k | { | 6793 | 56.8k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 56.8k | proj); | 6795 | 56.8k | } |
_ZNK4nano6ranges6detail10find_if_fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKcSB_LNS0_13subrange_kindE1EEEEENS0_8identityENS6_12function_refIFbcESI_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SG_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSM_EEEENS1_16projected_helperISU_SP_vEEEEEENSO_IX14borrowed_rangeISM_EEE4typeISU_NS0_8danglingEEEE4typeEOSM_SN_SP_ Line | Count | Source | 6792 | 240 | { | 6793 | 240 | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 240 | proj); | 6795 | 240 | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS7_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tEEENS8_15take_width_viewINS5_ISE_SF_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSI_0EEENS0_8identityENS8_12function_refIFbcESR_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SP_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSV_EEEENS1_16projected_helperIS13_SY_vEEEEEENSX_IX14borrowed_rangeISV_EEE4typeIS13_NS0_8danglingEEEE4typeEOSV_SW_SY_ Unexecuted instantiation: _ZNK4nano6ranges6detail10find_if_fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS5_6detail17basic_scan_bufferIcE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENS0_8identityENS6_12function_refIFbcESL_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SJ_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSP_EEEENS1_16projected_helperISX_SS_vEEEEEENSR_IX14borrowed_rangeISP_EEE4typeISX_NS0_8danglingEEEE4typeEOSP_SQ_SS_ _ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIPKwS7_LNS0_13subrange_kindE1EEENS0_8identityEN3scn2v24impl12function_refIFbwESG_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SB_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSK_EEEENS1_16projected_helperISS_SN_vEEEEEENSM_IX14borrowed_rangeISK_EEE4typeISS_NS0_8danglingEEEE4typeEOSK_SL_SN_ Line | Count | Source | 6792 | 1.14M | { | 6793 | 1.14M | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 1.14M | proj); | 6795 | 1.14M | } |
_ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorIPKwSC_EENS8_15take_width_viewINS5_ISC_SC_LNS0_13subrange_kindE1EEEE8sentinelILb1EEELSF_0EEENS0_8identityENS8_12function_refIFbwESO_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SM_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSS_EEEENS1_16projected_helperIS10_SV_vEEEEEENSU_IX14borrowed_rangeISS_EEE4typeIS10_NS0_8danglingEEEE4typeEOSS_ST_SV_ Line | Count | Source | 6792 | 970 | { | 6793 | 970 | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 970 | proj); | 6795 | 970 | } |
_ZNK4nano6ranges6detail10find_if_fnclIRKNSt3__16vectorINS4_4pairIDiDiEENS4_9allocatorIS7_EEEENS0_8identityEZNK3scn2v24impl25character_set_reader_implIwE12specs_helper29is_char_set_in_extra_literalsEDiEUlRKT_E_EENS4_9enable_ifIXaa11input_rangeISK_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SD_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSK_EEEENS1_16projected_helperISW_SR_vEEEEEENSQ_IX14borrowed_rangeISK_EEE4typeISW_NS0_8danglingEEEE4typeEOSK_SP_SR_ Line | Count | Source | 6792 | 55.7k | { | 6793 | 55.7k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 55.7k | proj); | 6795 | 55.7k | } |
_ZNK4nano6ranges6detail10find_if_fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeIPKwSB_LNS0_13subrange_kindE1EEEEENS0_8identityENS6_12function_refIFbwESI_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SG_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSM_EEEENS1_16projected_helperISU_SP_vEEEEEENSO_IX14borrowed_rangeISM_EEE4typeISU_NS0_8danglingEEEE4typeEOSM_SN_SP_ Line | Count | Source | 6792 | 138 | { | 6793 | 138 | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 138 | proj); | 6795 | 138 | } |
_ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v26detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEENS0_8identityENS7_4impl12function_refIFbwESJ_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SG_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSN_EEEENS1_16projected_helperISV_SQ_vEEEEEENSP_IX14borrowed_rangeISN_EEE4typeISV_NS0_8danglingEEEE4typeEOSN_SO_SQ_ Line | Count | Source | 6792 | 479k | { | 6793 | 479k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 479k | proj); | 6795 | 479k | } |
Unexecuted instantiation: _ZNK4nano6ranges6detail10find_if_fnclIRNS0_9subrange_8subrangeIN3scn2v24impl27counted_width_iterator_impl22counted_width_iteratorINS7_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tEEENS8_15take_width_viewINS5_ISE_SF_LNS0_13subrange_kindE0EEEE8sentinelILb1EEELSI_0EEENS0_8identityENS8_12function_refIFbwESR_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SP_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSV_EEEENS1_16projected_helperIS13_SY_vEEEEEENSX_IX14borrowed_rangeISV_EEE4typeIS13_NS0_8danglingEEEE4typeEOSV_SW_SY_ Unexecuted instantiation: _ZNK4nano6ranges6detail10find_if_fnclIRN3scn2v24impl15take_width_viewINS0_9subrange_8subrangeINS5_6detail17basic_scan_bufferIwE16forward_iteratorENS0_18default_sentinel_tELNS0_13subrange_kindE0EEEEENS0_8identityENS6_12function_refIFbwESL_EEEENSt3__19enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SJ_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSP_EEEENS1_16projected_helperISX_SS_vEEEEEENSR_IX14borrowed_rangeISP_EEE4typeISX_NS0_8danglingEEEE4typeEOSP_SQ_SS_ find_whitespace.cpp:_ZNK4nano6ranges6detail10find_if_fnclIRNSt3__117basic_string_viewIcNS4_11char_traitsIcEEEENS0_8identityEZN3scn2v24impl12_GLOBAL__N_133find_nondecimal_digit_simple_implES8_E3$_0EENS4_9enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SA_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSH_EEEENS1_16projected_helperISP_SK_vEEEEEENSJ_IX14borrowed_rangeISH_EEE4typeISP_NS0_8danglingEEEE4typeEOSH_SI_SK_ Line | Count | Source | 6792 | 178k | { | 6793 | 178k | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 178k | proj); | 6795 | 178k | } |
find_whitespace.cpp:_ZNK4nano6ranges6detail10find_if_fnclIRNSt3__117basic_string_viewIcNS4_11char_traitsIcEEEENS0_8identityEZN3scn2v24impl30find_classic_space_narrow_fastES8_E3$_0EENS4_9enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SA_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSG_EEEENS1_16projected_helperISO_SJ_vEEEEEENSI_IX14borrowed_rangeISG_EEE4typeISO_NS0_8danglingEEEE4typeEOSG_SH_SJ_ Line | Count | Source | 6792 | 5.81M | { | 6793 | 5.81M | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 5.81M | proj); | 6795 | 5.81M | } |
find_whitespace.cpp:_ZNK4nano6ranges6detail10find_if_fnclIRNSt3__117basic_string_viewIcNS4_11char_traitsIcEEEENS0_8identityEZN3scn2v24impl33find_classic_nonspace_narrow_fastES8_E3$_0EENS4_9enable_ifIXaa11input_rangeIT_E24indirect_unary_predicateIT1_NS1_11conditionalIX7same_asIT0_SA_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSG_EEEENS1_16projected_helperISO_SJ_vEEEEEENSI_IX14borrowed_rangeISG_EEE4typeISO_NS0_8danglingEEEE4typeEOSG_SH_SJ_ Line | Count | Source | 6792 | 6.15M | { | 6793 | 6.15M | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, | 6794 | 6.15M | proj); | 6795 | 6.15M | } |
|
6796 | | }; |
6797 | | } // namespace detail |
6798 | | |
6799 | | NANO_INLINE_VAR(detail::find_if_fn, find_if) |
6800 | | |
6801 | | namespace detail { |
6802 | | |
6803 | | struct find_fn { |
6804 | | template <typename I, typename S, typename T, typename Proj = identity> |
6805 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
6806 | | indirect_relation<ranges::equal_to, |
6807 | | projected<I, Proj>, |
6808 | | const T*>, |
6809 | | I> |
6810 | | operator()(I first, S last, const T& value, Proj proj = Proj{}) const |
6811 | | { |
6812 | | const auto pred = [&value](const auto& t) { return t == value; }; |
6813 | | return find_if_fn::impl(std::move(first), std::move(last), pred, |
6814 | | proj); |
6815 | | } |
6816 | | |
6817 | | template <typename Rng, typename T, typename Proj = identity> |
6818 | | constexpr std::enable_if_t< |
6819 | | input_range<Rng> && |
6820 | | indirect_relation<ranges::equal_to, |
6821 | | projected<iterator_t<Rng>, Proj>, |
6822 | | const T*>, |
6823 | | borrowed_iterator_t<Rng>> |
6824 | | operator()(Rng&& rng, const T& value, Proj proj = Proj{}) const |
6825 | 0 | { |
6826 | 0 | const auto pred = [&value](const auto& t) { return t == value; };Unexecuted instantiation: _ZZNK4nano6ranges6detail7find_fnclIRNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEcNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SC_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSE_EEEENS1_16projected_helperISM_SH_vEEEEPKT0_EENSG_IX14borrowed_rangeISE_EEE4typeISM_NS0_8danglingEEEE4typeEOSE_RSR_SH_ENKUlRKSE_E_clIcEEDaS12_ Unexecuted instantiation: _ZZNK4nano6ranges6detail7find_fnclIRNSt3__112basic_stringIwNS4_11char_traitsIwEENS4_9allocatorIwEEEEwNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SC_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSE_EEEENS1_16projected_helperISM_SH_vEEEEPKT0_EENSG_IX14borrowed_rangeISE_EEE4typeISM_NS0_8danglingEEEE4typeEOSE_RSR_SH_ENKUlRKSE_E_clIwEEDaS12_ |
6827 | 0 | return find_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
6828 | 0 | proj); |
6829 | 0 | } Unexecuted instantiation: _ZNK4nano6ranges6detail7find_fnclIRNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEcNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SC_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSE_EEEENS1_16projected_helperISM_SH_vEEEEPKT0_EENSG_IX14borrowed_rangeISE_EEE4typeISM_NS0_8danglingEEEE4typeEOSE_RSR_SH_ Unexecuted instantiation: _ZNK4nano6ranges6detail7find_fnclIRNSt3__112basic_stringIwNS4_11char_traitsIwEENS4_9allocatorIwEEEEwNS0_8identityEEENS4_9enable_ifIXaa11input_rangeIT_E17indirect_relationINS0_8equal_toENS1_11conditionalIX7same_asIT1_SC_EEE4typeIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRSE_EEEENS1_16projected_helperISM_SH_vEEEEPKT0_EENSG_IX14borrowed_rangeISE_EEE4typeISM_NS0_8danglingEEEE4typeEOSE_RSR_SH_ |
6830 | | }; |
6831 | | } // namespace detail |
6832 | | |
6833 | | NANO_INLINE_VAR(detail::find_fn, find) |
6834 | | |
6835 | | namespace detail { |
6836 | | |
6837 | | struct find_if_not_fn { |
6838 | | private: |
6839 | | template <typename Pred> |
6840 | | struct not_pred { |
6841 | | Pred& p; |
6842 | | |
6843 | | template <typename T> |
6844 | | constexpr bool operator()(T&& t) const |
6845 | | { |
6846 | | return !nano::invoke(p, std::forward<T>(t)); |
6847 | | } |
6848 | | }; |
6849 | | |
6850 | | public: |
6851 | | template <typename I, |
6852 | | typename S, |
6853 | | typename Proj = identity, |
6854 | | typename Pred> |
6855 | | constexpr std::enable_if_t< |
6856 | | input_iterator<I> && sentinel_for<S, I> && |
6857 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
6858 | | I> |
6859 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
6860 | | { |
6861 | | const auto find_if_pred = not_pred<Pred>{pred}; |
6862 | | return find_if_fn::impl(std::move(first), std::move(last), |
6863 | | find_if_pred, proj); |
6864 | | } |
6865 | | |
6866 | | template <typename Rng, typename Proj = identity, typename Pred> |
6867 | | constexpr std::enable_if_t< |
6868 | | input_range<Rng> && |
6869 | | indirect_unary_predicate<Pred, |
6870 | | projected<iterator_t<Rng>, Proj>>, |
6871 | | borrowed_iterator_t<Rng>> |
6872 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
6873 | | { |
6874 | | const auto find_if_pred = not_pred<Pred>{pred}; |
6875 | | return find_if_fn::impl(nano::begin(rng), nano::end(rng), |
6876 | | find_if_pred, proj); |
6877 | | } |
6878 | | }; |
6879 | | } // namespace detail |
6880 | | |
6881 | | NANO_INLINE_VAR(detail::find_if_not_fn, find_if_not) |
6882 | | |
6883 | | NANO_END_NAMESPACE |
6884 | | |
6885 | | #endif |
6886 | | |
6887 | | // nanorange/algorithm/find_end.hpp |
6888 | | // |
6889 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6890 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
6891 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6892 | | |
6893 | | #ifndef NANORANGE_ALGORITHM_FIND_END_HPP_INCLUDED |
6894 | | #define NANORANGE_ALGORITHM_FIND_END_HPP_INCLUDED |
6895 | | |
6896 | | // nanorange/algorithm/search.hpp |
6897 | | // |
6898 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
6899 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
6900 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6901 | | |
6902 | | #ifndef NANORANGE_ALGORITHM_SEARCH_HPP_INCLUDED |
6903 | | #define NANORANGE_ALGORITHM_SEARCH_HPP_INCLUDED |
6904 | | |
6905 | | NANO_BEGIN_NAMESPACE |
6906 | | |
6907 | | namespace detail { |
6908 | | |
6909 | | struct search_fn { |
6910 | | private: |
6911 | | friend struct find_end_fn; |
6912 | | |
6913 | | template <typename I1, |
6914 | | typename S1, |
6915 | | typename I2, |
6916 | | typename S2, |
6917 | | typename Pred, |
6918 | | typename Proj1, |
6919 | | typename Proj2 = identity> |
6920 | | static constexpr subrange<I1> impl(I1 first1, |
6921 | | S1 last1, |
6922 | | I2 first2, |
6923 | | S2 last2, |
6924 | | Pred& pred, |
6925 | | Proj1& proj1, |
6926 | | Proj2& proj2) |
6927 | | { |
6928 | | while (true) { |
6929 | | auto it1 = first1; |
6930 | | auto it2 = first2; |
6931 | | |
6932 | | while (true) { |
6933 | | if (it2 == last2) { |
6934 | | return {first1, it1}; |
6935 | | } |
6936 | | if (it1 == last1) { |
6937 | | return {it1, it1}; |
6938 | | } |
6939 | | if (!nano::invoke(pred, nano::invoke(proj1, *it1), |
6940 | | nano::invoke(proj2, *it2))) { |
6941 | | break; |
6942 | | } |
6943 | | ++it1; |
6944 | | ++it2; |
6945 | | } |
6946 | | |
6947 | | ++first1; |
6948 | | } |
6949 | | } |
6950 | | |
6951 | | public: |
6952 | | template <typename I1, |
6953 | | typename S1, |
6954 | | typename I2, |
6955 | | typename S2, |
6956 | | typename Pred = ranges::equal_to, |
6957 | | typename Proj1 = identity, |
6958 | | typename Proj2 = identity> |
6959 | | constexpr std::enable_if_t< |
6960 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
6961 | | forward_iterator<I2> && sentinel_for<S2, I2> && |
6962 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2>, |
6963 | | subrange<I1>> |
6964 | | operator()(I1 first1, |
6965 | | S1 last1, |
6966 | | I2 first2, |
6967 | | S2 last2, |
6968 | | Pred pred = Pred{}, |
6969 | | Proj1 proj1 = Proj1{}, |
6970 | | Proj2 proj2 = Proj2{}) const |
6971 | | { |
6972 | | return search_fn::impl(std::move(first1), std::move(last1), |
6973 | | std::move(first2), std::move(last2), pred, |
6974 | | proj1, proj2); |
6975 | | } |
6976 | | |
6977 | | template <typename Rng1, |
6978 | | typename Rng2, |
6979 | | typename Pred = ranges::equal_to, |
6980 | | typename Proj1 = identity, |
6981 | | typename Proj2 = identity> |
6982 | | constexpr std::enable_if_t<forward_range<Rng1> && forward_range<Rng2> && |
6983 | | indirectly_comparable<iterator_t<Rng1>, |
6984 | | iterator_t<Rng2>, |
6985 | | Pred, |
6986 | | Proj1, |
6987 | | Proj2>, |
6988 | | borrowed_subrange_t<Rng1>> |
6989 | | operator()(Rng1&& rng1, |
6990 | | Rng2&& rng2, |
6991 | | Pred pred = Pred{}, |
6992 | | Proj1 proj1 = Proj1{}, |
6993 | | Proj2 proj2 = Proj2{}) const |
6994 | | { |
6995 | | return search_fn::impl(nano::begin(rng1), nano::end(rng1), |
6996 | | nano::begin(rng2), nano::end(rng2), pred, |
6997 | | proj1, proj2); |
6998 | | } |
6999 | | }; |
7000 | | |
7001 | | } // namespace detail |
7002 | | |
7003 | | NANO_INLINE_VAR(detail::search_fn, search) |
7004 | | |
7005 | | NANO_END_NAMESPACE |
7006 | | |
7007 | | #endif |
7008 | | |
7009 | | NANO_BEGIN_NAMESPACE |
7010 | | |
7011 | | // [ranges.alg.find.end] |
7012 | | namespace detail { |
7013 | | |
7014 | | // TODO: For BiDir iterators, we can be smarter and search backwards |
7015 | | struct find_end_fn { |
7016 | | private: |
7017 | | template <typename I1, |
7018 | | typename S1, |
7019 | | typename I2, |
7020 | | typename S2, |
7021 | | typename Pred, |
7022 | | typename Proj1, |
7023 | | typename Proj2> |
7024 | | static constexpr subrange<I1> impl(I1 first1, |
7025 | | S1 last1, |
7026 | | I2 first2, |
7027 | | S2 last2, |
7028 | | Pred& pred, |
7029 | | Proj1& proj1, |
7030 | | Proj2& proj2) |
7031 | | { |
7032 | | if (first2 == last2) { |
7033 | | auto last_it = nano::next(first1, last1); |
7034 | | return {last_it, last_it}; |
7035 | | } |
7036 | | |
7037 | | auto result = search_fn::impl(std::move(first1), last1, first2, |
7038 | | last2, pred, proj1, proj2); |
7039 | | |
7040 | | if (result.empty()) { |
7041 | | return result; |
7042 | | } |
7043 | | |
7044 | | while (true) { |
7045 | | auto new_result = |
7046 | | search_fn::impl(next(result.begin()), last1, first2, last2, |
7047 | | pred, proj1, proj2); |
7048 | | if (new_result.empty()) { |
7049 | | return result; |
7050 | | } |
7051 | | else { |
7052 | | result = std::move(new_result); |
7053 | | } |
7054 | | } |
7055 | | } |
7056 | | |
7057 | | public: |
7058 | | template <typename I1, |
7059 | | typename S1, |
7060 | | typename I2, |
7061 | | typename S2, |
7062 | | typename Pred = ranges::equal_to, |
7063 | | typename Proj1 = identity, |
7064 | | typename Proj2 = identity> |
7065 | | constexpr std::enable_if_t< |
7066 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
7067 | | forward_iterator<I2> && sentinel_for<S2, I2> && |
7068 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2>, |
7069 | | subrange<I1>> |
7070 | | operator()(I1 first1, |
7071 | | S1 last1, |
7072 | | I2 first2, |
7073 | | S2 last2, |
7074 | | Pred pred = Pred{}, |
7075 | | Proj1 proj1 = Proj1{}, |
7076 | | Proj2 proj2 = Proj2{}) const |
7077 | | { |
7078 | | return find_end_fn::impl(std::move(first1), std::move(last1), |
7079 | | std::move(first2), std::move(last2), pred, |
7080 | | proj1, proj2); |
7081 | | } |
7082 | | |
7083 | | template <typename Rng1, |
7084 | | typename Rng2, |
7085 | | typename Pred = ranges::equal_to, |
7086 | | typename Proj1 = identity, |
7087 | | typename Proj2 = identity> |
7088 | | constexpr std::enable_if_t<forward_range<Rng1> && forward_range<Rng2> && |
7089 | | indirectly_comparable<iterator_t<Rng1>, |
7090 | | iterator_t<Rng2>, |
7091 | | Pred, |
7092 | | Proj1, |
7093 | | Proj2>, |
7094 | | borrowed_subrange_t<Rng1>> |
7095 | | operator()(Rng1&& rng1, |
7096 | | Rng2&& rng2, |
7097 | | Pred pred = Pred{}, |
7098 | | Proj1 proj1 = Proj1{}, |
7099 | | Proj2 proj2 = Proj2{}) const |
7100 | | { |
7101 | | return find_end_fn::impl(nano::begin(rng1), nano::end(rng1), |
7102 | | nano::begin(rng2), nano::end(rng2), pred, |
7103 | | proj1, proj2); |
7104 | | } |
7105 | | }; |
7106 | | |
7107 | | } // namespace detail |
7108 | | |
7109 | | NANO_INLINE_VAR(detail::find_end_fn, find_end) |
7110 | | |
7111 | | NANO_END_NAMESPACE |
7112 | | |
7113 | | #endif |
7114 | | |
7115 | | // nanorange/algorithm/find_first_of.hpp |
7116 | | // |
7117 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7118 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7119 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7120 | | |
7121 | | #ifndef NANORANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED |
7122 | | #define NANORANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED |
7123 | | |
7124 | | NANO_BEGIN_NAMESPACE |
7125 | | |
7126 | | // [range.alg.find.first.of] |
7127 | | |
7128 | | namespace detail { |
7129 | | |
7130 | | struct find_first_of_fn { |
7131 | | private: |
7132 | | template <typename I1, |
7133 | | typename S1, |
7134 | | typename I2, |
7135 | | typename S2, |
7136 | | typename Pred, |
7137 | | typename Proj1, |
7138 | | typename Proj2> |
7139 | | static constexpr I1 impl(I1 first1, |
7140 | | S1 last1, |
7141 | | I2 first2, |
7142 | | S2 last2, |
7143 | | Pred& pred, |
7144 | | Proj1& proj1, |
7145 | | Proj2& proj2) |
7146 | | { |
7147 | | for (; first1 != last1; ++first1) { |
7148 | | for (I2 it = first2; it != last2; ++it) { |
7149 | | if (nano::invoke(pred, nano::invoke(proj1, *first1), |
7150 | | nano::invoke(proj2, *it))) { |
7151 | | return first1; |
7152 | | } |
7153 | | } |
7154 | | } |
7155 | | |
7156 | | return first1; |
7157 | | } |
7158 | | |
7159 | | public: |
7160 | | template <typename I1, |
7161 | | typename S1, |
7162 | | typename I2, |
7163 | | typename S2, |
7164 | | typename Proj1 = identity, |
7165 | | typename Proj2 = identity, |
7166 | | typename Pred = ranges::equal_to> |
7167 | | constexpr std::enable_if_t<input_iterator<I1> && sentinel_for<S1, I1> && |
7168 | | forward_iterator<I2> && |
7169 | | sentinel_for<S2, I2> && |
7170 | | indirect_relation<Pred, |
7171 | | projected<I1, Proj1>, |
7172 | | projected<I2, Proj2>>, |
7173 | | I1> |
7174 | | operator()(I1 first1, |
7175 | | S1 last1, |
7176 | | I2 first2, |
7177 | | S2 last2, |
7178 | | Pred pred = Pred{}, |
7179 | | Proj1 proj1 = Proj1{}, |
7180 | | Proj2 proj2 = Proj2{}) const |
7181 | | { |
7182 | | return find_first_of_fn::impl(std::move(first1), std::move(last1), |
7183 | | std::move(first2), std::move(last2), |
7184 | | pred, proj1, proj2); |
7185 | | } |
7186 | | |
7187 | | template <typename Rng1, |
7188 | | typename Rng2, |
7189 | | typename Proj1 = identity, |
7190 | | typename Proj2 = identity, |
7191 | | typename Pred = ranges::equal_to> |
7192 | | constexpr std::enable_if_t< |
7193 | | input_range<Rng1> && forward_range<Rng2> && |
7194 | | indirect_relation<Pred, |
7195 | | projected<iterator_t<Rng1>, Proj1>, |
7196 | | projected<iterator_t<Rng2>, Proj2>>, |
7197 | | borrowed_iterator_t<Rng1>> |
7198 | | operator()(Rng1&& rng1, |
7199 | | Rng2&& rng2, |
7200 | | Pred pred = Pred{}, |
7201 | | Proj1 proj1 = Proj1{}, |
7202 | | Proj2 proj2 = Proj2{}) const |
7203 | | { |
7204 | | return find_first_of_fn::impl(nano::begin(rng1), nano::end(rng1), |
7205 | | nano::begin(rng2), nano::end(rng2), |
7206 | | pred, proj1, proj2); |
7207 | | } |
7208 | | }; |
7209 | | |
7210 | | } // namespace detail |
7211 | | |
7212 | | NANO_INLINE_VAR(detail::find_first_of_fn, find_first_of) |
7213 | | |
7214 | | NANO_END_NAMESPACE |
7215 | | |
7216 | | #endif |
7217 | | // nanorange/algorithm/for_each.hpp |
7218 | | // |
7219 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7220 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7221 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7222 | | |
7223 | | #ifndef NANORANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED |
7224 | | #define NANORANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED |
7225 | | |
7226 | | NANO_BEGIN_NAMESPACE |
7227 | | |
7228 | | // [range.alg.foreach] |
7229 | | |
7230 | | template <typename I, typename F> |
7231 | | using for_each_result = in_fun_result<I, F>; |
7232 | | |
7233 | | namespace detail { |
7234 | | |
7235 | | struct for_each_fn { |
7236 | | private: |
7237 | | template <typename I, typename S, typename Proj, typename Fun> |
7238 | | static constexpr for_each_result<I, Fun> impl(I first, |
7239 | | S last, |
7240 | | Fun& fun, |
7241 | | Proj& proj) |
7242 | | { |
7243 | | while (first != last) { |
7244 | | nano::invoke(fun, nano::invoke(proj, *first)); |
7245 | | ++first; |
7246 | | } |
7247 | | return {first, std::move(fun)}; |
7248 | | } |
7249 | | |
7250 | | public: |
7251 | | template <typename I, |
7252 | | typename S, |
7253 | | typename Proj = identity, |
7254 | | typename Fun> |
7255 | | constexpr std::enable_if_t< |
7256 | | input_iterator<I> && sentinel_for<S, I> && |
7257 | | indirect_unary_invocable<Fun, projected<I, Proj>>, |
7258 | | for_each_result<I, Fun>> |
7259 | | operator()(I first, S last, Fun fun, Proj proj = Proj{}) const |
7260 | | { |
7261 | | return for_each_fn::impl(std::move(first), std::move(last), fun, |
7262 | | proj); |
7263 | | } |
7264 | | |
7265 | | template <typename Rng, typename Proj = identity, typename Fun> |
7266 | | constexpr std::enable_if_t< |
7267 | | input_range<Rng> && |
7268 | | indirect_unary_invocable<Fun, projected<iterator_t<Rng>, Proj>>, |
7269 | | for_each_result<borrowed_iterator_t<Rng>, Fun>> |
7270 | | operator()(Rng&& rng, Fun fun, Proj proj = Proj{}) const |
7271 | | { |
7272 | | return for_each_fn::impl(nano::begin(rng), nano::end(rng), fun, |
7273 | | proj); |
7274 | | } |
7275 | | }; |
7276 | | } // namespace detail |
7277 | | |
7278 | | NANO_INLINE_VAR(detail::for_each_fn, for_each) |
7279 | | |
7280 | | template <typename I, typename F> |
7281 | | using for_each_n_result = in_fun_result<I, F>; |
7282 | | |
7283 | | namespace detail { |
7284 | | |
7285 | | struct for_each_n_fn { |
7286 | | template <typename I, typename Proj = identity, typename Fun> |
7287 | | constexpr std::enable_if_t< |
7288 | | input_iterator<I> && |
7289 | | indirect_unary_invocable<Fun, projected<I, Proj>>, |
7290 | | for_each_n_result<I, Fun>> |
7291 | | operator()(I first, |
7292 | | iter_difference_t<I> n, |
7293 | | Fun fun, |
7294 | | Proj proj = Proj{}) const |
7295 | | { |
7296 | | while (n-- > 0) { |
7297 | | nano::invoke(fun, nano::invoke(proj, *first)); |
7298 | | ++first; |
7299 | | } |
7300 | | return {std::move(first), std::move(fun)}; |
7301 | | } |
7302 | | }; |
7303 | | } // namespace detail |
7304 | | |
7305 | | NANO_INLINE_VAR(detail::for_each_n_fn, for_each_n) |
7306 | | |
7307 | | NANO_END_NAMESPACE |
7308 | | |
7309 | | #endif |
7310 | | |
7311 | | // nanorange/algorithm/generate.hpp |
7312 | | // |
7313 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7314 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7315 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7316 | | |
7317 | | #ifndef NANORANGE_ALGORITHM_GENERATE_HPP_INCLUDED |
7318 | | #define NANORANGE_ALGORITHM_GENERATE_HPP_INCLUDED |
7319 | | |
7320 | | NANO_BEGIN_NAMESPACE |
7321 | | |
7322 | | namespace detail { |
7323 | | |
7324 | | struct generate_fn { |
7325 | | private: |
7326 | | template <typename O, typename S, typename F> |
7327 | | static constexpr O impl(O first, S last, F& gen) |
7328 | | { |
7329 | | while (first != last) { |
7330 | | *first = gen(); |
7331 | | ++first; |
7332 | | } |
7333 | | |
7334 | | return first; |
7335 | | } |
7336 | | |
7337 | | public: |
7338 | | template <typename O, typename S, typename F> |
7339 | | constexpr std::enable_if_t<input_or_output_iterator<O> && |
7340 | | sentinel_for<S, O> && |
7341 | | copy_constructible<F> && invocable<F&> && |
7342 | | writable<O, invoke_result_t<F&>>, |
7343 | | O> |
7344 | | operator()(O first, S last, F gen) const |
7345 | | { |
7346 | | return generate_fn::impl(std::move(first), std::move(last), gen); |
7347 | | } |
7348 | | |
7349 | | template <typename Rng, typename F> |
7350 | | constexpr std::enable_if_t<invocable<F&> && |
7351 | | output_range<Rng, invoke_result_t<F&>>, |
7352 | | borrowed_iterator_t<Rng>> |
7353 | | operator()(Rng&& rng, F gen) const |
7354 | | { |
7355 | | return generate_fn::impl(nano::begin(rng), nano::end(rng), gen); |
7356 | | } |
7357 | | }; |
7358 | | |
7359 | | } // namespace detail |
7360 | | |
7361 | | NANO_INLINE_VAR(detail::generate_fn, generate) |
7362 | | |
7363 | | NANO_END_NAMESPACE |
7364 | | |
7365 | | #endif |
7366 | | |
7367 | | // nanorange/algorithm/generate_n.hpp |
7368 | | // |
7369 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7370 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7371 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7372 | | |
7373 | | #ifndef NANORANGE_ALGORITHM_GENERATE_N_HPP_INCLUDED |
7374 | | #define NANORANGE_ALGORITHM_GENERATE_N_HPP_INCLUDED |
7375 | | |
7376 | | NANO_BEGIN_NAMESPACE |
7377 | | |
7378 | | namespace detail { |
7379 | | |
7380 | | struct generate_n_fn { |
7381 | | template <typename O, typename F> |
7382 | | constexpr std::enable_if_t<input_or_output_iterator<O> && |
7383 | | copy_constructible<F> && invocable<F&> && |
7384 | | writable<O, invoke_result_t<F&>>, |
7385 | | O> |
7386 | | operator()(O first, iter_difference_t<O> n, F gen) const |
7387 | | { |
7388 | | for (iter_difference_t<O> i{0}; i < n; ++i, ++first) { |
7389 | | *first = gen(); |
7390 | | } |
7391 | | |
7392 | | return first; |
7393 | | } |
7394 | | }; |
7395 | | |
7396 | | } // namespace detail |
7397 | | |
7398 | | NANO_INLINE_VAR(detail::generate_n_fn, generate_n) |
7399 | | |
7400 | | NANO_END_NAMESPACE |
7401 | | |
7402 | | #endif |
7403 | | |
7404 | | // nanorange/algorithm/includes.hpp |
7405 | | // |
7406 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7407 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7408 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7409 | | |
7410 | | #ifndef NANORANGE_ALGORITHM_INCLUDES_HPP_INCLUDED |
7411 | | #define NANORANGE_ALGORITHM_INCLUDES_HPP_INCLUDED |
7412 | | |
7413 | | NANO_BEGIN_NAMESPACE |
7414 | | |
7415 | | namespace detail { |
7416 | | |
7417 | | struct includes_fn { |
7418 | | private: |
7419 | | template <typename I1, |
7420 | | typename S1, |
7421 | | typename I2, |
7422 | | typename S2, |
7423 | | typename Comp, |
7424 | | typename Proj1, |
7425 | | typename Proj2> |
7426 | | static constexpr bool impl(I1 first1, |
7427 | | S1 last1, |
7428 | | I2 first2, |
7429 | | S2 last2, |
7430 | | Comp& comp, |
7431 | | Proj1& proj1, |
7432 | | Proj2& proj2) |
7433 | | { |
7434 | | while (first2 != last2) { |
7435 | | // If range1 is done but we still have elements in range2, then |
7436 | | // it is not a subset |
7437 | | if (first1 == last1) { |
7438 | | return false; |
7439 | | } |
7440 | | |
7441 | | // If the current element of r2 is less than the current |
7442 | | // element of r1, then it is not in r1 => not a subset |
7443 | | if (nano::invoke(comp, nano::invoke(proj2, *first2), |
7444 | | nano::invoke(proj1, *first1))) { |
7445 | | return false; |
7446 | | } |
7447 | | |
7448 | | // Now we know that that !(r2 < r1). If we also have !(r1 < r2), |
7449 | | // then it must be equal, so in range1 -- so move onto the next |
7450 | | // element |
7451 | | if (!nano::invoke(comp, nano::invoke(proj1, *first1), |
7452 | | nano::invoke(proj2, *first2))) { |
7453 | | ++first2; |
7454 | | } |
7455 | | |
7456 | | ++first1; |
7457 | | } |
7458 | | |
7459 | | return true; |
7460 | | } |
7461 | | |
7462 | | public: |
7463 | | template <typename I1, |
7464 | | typename S1, |
7465 | | typename I2, |
7466 | | typename S2, |
7467 | | typename Comp = ranges::less, |
7468 | | typename Proj1 = identity, |
7469 | | typename Proj2 = identity> |
7470 | | constexpr std::enable_if_t< |
7471 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
7472 | | sentinel_for<S2, I2> && |
7473 | | indirect_strict_weak_order<Comp, |
7474 | | projected<I1, Proj1>, |
7475 | | projected<I2, Proj2>>, |
7476 | | bool> |
7477 | | operator()(I1 first1, |
7478 | | S1 last1, |
7479 | | I2 first2, |
7480 | | S2 last2, |
7481 | | Comp comp = Comp{}, |
7482 | | Proj1 proj1 = Proj1{}, |
7483 | | Proj2 proj2 = Proj2{}) const |
7484 | | { |
7485 | | return includes_fn::impl(std::move(first1), std::move(last1), |
7486 | | std::move(first2), std::move(last2), comp, |
7487 | | proj1, proj2); |
7488 | | } |
7489 | | |
7490 | | template <typename Rng1, |
7491 | | typename Rng2, |
7492 | | typename Comp = ranges::less, |
7493 | | typename Proj1 = identity, |
7494 | | typename Proj2 = identity> |
7495 | | constexpr std::enable_if_t< |
7496 | | input_range<Rng1> && input_range<Rng2> && |
7497 | | indirect_strict_weak_order<Comp, |
7498 | | projected<iterator_t<Rng1>, Proj1>, |
7499 | | projected<iterator_t<Rng2>, Proj2>>, |
7500 | | bool> |
7501 | | operator()(Rng1&& rng1, |
7502 | | Rng2&& rng2, |
7503 | | Comp comp = Comp{}, |
7504 | | Proj1 proj1 = Proj1{}, |
7505 | | Proj2 proj2 = Proj2{}) const |
7506 | | { |
7507 | | return includes_fn::impl(nano::begin(rng1), nano::end(rng1), |
7508 | | nano::begin(rng2), nano::end(rng2), comp, |
7509 | | proj1, proj2); |
7510 | | } |
7511 | | }; |
7512 | | |
7513 | | } // namespace detail |
7514 | | |
7515 | | NANO_INLINE_VAR(detail::includes_fn, includes) |
7516 | | |
7517 | | NANO_END_NAMESPACE |
7518 | | |
7519 | | #endif |
7520 | | |
7521 | | // nanorange/algorithm/inplace_merge.hpp |
7522 | | // |
7523 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
7524 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7525 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7526 | | |
7527 | | // Uses code from cmcstl2 - A concept-enabled C++ standard library |
7528 | | // |
7529 | | // Copyright Eric Niebler 2014 |
7530 | | // Copyright Casey Carter 2015 |
7531 | | // |
7532 | | |
7533 | | //===----------------------------------------------------------------------===// |
7534 | | // |
7535 | | // The LLVM Compiler Infrastructure |
7536 | | // |
7537 | | // This file is dual licensed under the MIT and the University of Illinois Open |
7538 | | // Source Licenses. See LICENSE.TXT for details. |
7539 | | // |
7540 | | //===----------------------------------------------------------------------===// |
7541 | | |
7542 | | #ifndef NANORANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED |
7543 | | #define NANORANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED |
7544 | | |
7545 | | // nanorange/algorithm/merge.hpp |
7546 | | // |
7547 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7548 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7549 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7550 | | |
7551 | | #ifndef NANORANGE_ALGORITHM_MERGE_HPP_INCLUDED |
7552 | | #define NANORANGE_ALGORITHM_MERGE_HPP_INCLUDED |
7553 | | |
7554 | | NANO_BEGIN_NAMESPACE |
7555 | | |
7556 | | template <typename I1, typename I2, typename O> |
7557 | | using merge_result = in_in_out_result<I1, I2, O>; |
7558 | | |
7559 | | namespace detail { |
7560 | | |
7561 | | struct merge_fn { |
7562 | | private: |
7563 | | template <typename I1, |
7564 | | typename S1, |
7565 | | typename I2, |
7566 | | typename S2, |
7567 | | typename O, |
7568 | | typename Comp, |
7569 | | typename Proj1, |
7570 | | typename Proj2> |
7571 | | static constexpr merge_result<I1, I2, O> impl(I1 first1, |
7572 | | S1 last1, |
7573 | | I2 first2, |
7574 | | S2 last2, |
7575 | | O result, |
7576 | | Comp& comp, |
7577 | | Proj1& proj1, |
7578 | | Proj2& proj2) |
7579 | | { |
7580 | | while (first1 != last1) { |
7581 | | // If we've reached the end of the second range, copy any |
7582 | | // remaining elements from the first range directly |
7583 | | if (first2 == last2) { |
7584 | | auto res = nano::copy(std::move(first1), std::move(last1), |
7585 | | std::move(result)); |
7586 | | first1 = std::move(res.in); |
7587 | | result = std::move(res.out); |
7588 | | break; |
7589 | | } |
7590 | | |
7591 | | // (Only) if the element from range2 compares less than the |
7592 | | // element from range1, copy it. Otherwise copy the element from |
7593 | | // the first |
7594 | | if (nano::invoke(comp, nano::invoke(proj2, *first2), |
7595 | | nano::invoke(proj1, *first1))) { |
7596 | | *result = *first2; |
7597 | | ++first2; |
7598 | | } |
7599 | | else { |
7600 | | *result = *first1; |
7601 | | ++first1; |
7602 | | } |
7603 | | ++result; |
7604 | | } |
7605 | | |
7606 | | // We've reached the end of range1, so copy any remaining elements |
7607 | | // from range2 |
7608 | | auto res = nano::copy(std::move(first2), std::move(last2), |
7609 | | std::move(result)); |
7610 | | first2 = std::move(res.in); |
7611 | | result = std::move(res.out); |
7612 | | |
7613 | | return {std::move(first1), std::move(first2), std::move(result)}; |
7614 | | } |
7615 | | |
7616 | | public: |
7617 | | template <typename I1, |
7618 | | typename S1, |
7619 | | typename I2, |
7620 | | typename S2, |
7621 | | typename O, |
7622 | | typename Comp = ranges::less, |
7623 | | typename Proj1 = identity, |
7624 | | typename Proj2 = identity> |
7625 | | constexpr std::enable_if_t< |
7626 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
7627 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
7628 | | mergeable<I1, I2, O, Comp, Proj1, Proj1>, |
7629 | | merge_result<I1, I2, O>> |
7630 | | operator()(I1 first1, |
7631 | | S1 last1, |
7632 | | I2 first2, |
7633 | | S2 last2, |
7634 | | O result, |
7635 | | Comp comp = Comp{}, |
7636 | | Proj1 proj1 = Proj1{}, |
7637 | | Proj2 proj2 = Proj2{}) const |
7638 | | { |
7639 | | return merge_fn::impl(std::move(first1), std::move(last1), |
7640 | | std::move(first2), std::move(last2), |
7641 | | std::move(result), comp, proj1, proj2); |
7642 | | } |
7643 | | |
7644 | | template <typename Rng1, |
7645 | | typename Rng2, |
7646 | | typename O, |
7647 | | typename Comp = ranges::less, |
7648 | | typename Proj1 = identity, |
7649 | | typename Proj2 = identity> |
7650 | | constexpr std::enable_if_t<input_range<Rng1> && input_range<Rng2> && |
7651 | | weakly_incrementable<O> && |
7652 | | mergeable<iterator_t<Rng1>, |
7653 | | iterator_t<Rng2>, |
7654 | | O, |
7655 | | Comp, |
7656 | | Proj1, |
7657 | | Proj2>, |
7658 | | merge_result<borrowed_iterator_t<Rng1>, |
7659 | | borrowed_iterator_t<Rng2>, |
7660 | | O>> |
7661 | | operator()(Rng1&& rng1, |
7662 | | Rng2&& rng2, |
7663 | | O result, |
7664 | | Comp comp = Comp{}, |
7665 | | Proj1 proj1 = Proj1{}, |
7666 | | Proj2 proj2 = Proj2{}) const |
7667 | | { |
7668 | | return merge_fn::impl(nano::begin(rng1), nano::end(rng1), |
7669 | | nano::begin(rng2), nano::end(rng2), |
7670 | | std::move(result), comp, proj1, proj2); |
7671 | | } |
7672 | | }; |
7673 | | |
7674 | | } // namespace detail |
7675 | | |
7676 | | NANO_INLINE_VAR(detail::merge_fn, merge) |
7677 | | |
7678 | | NANO_END_NAMESPACE |
7679 | | |
7680 | | #endif |
7681 | | |
7682 | | // nanorange/algorithm/min.hpp |
7683 | | // |
7684 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7685 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7686 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7687 | | |
7688 | | #ifndef NANORANGE_ALGORITHM_MIN_HPP_INCLUDED |
7689 | | #define NANORANGE_ALGORITHM_MIN_HPP_INCLUDED |
7690 | | |
7691 | | NANO_BEGIN_NAMESPACE |
7692 | | |
7693 | | namespace detail { |
7694 | | |
7695 | | struct min_fn { |
7696 | | private: |
7697 | | template <typename Rng, typename Comp, typename Proj> |
7698 | | static constexpr iter_value_t<iterator_t<Rng>> impl(Rng&& rng, |
7699 | | Comp& comp, |
7700 | | Proj& proj) |
7701 | | { |
7702 | | auto first = nano::begin(rng); |
7703 | | const auto last = nano::end(rng); |
7704 | | |
7705 | | // Empty ranges not allowed |
7706 | | auto result = *first; |
7707 | | |
7708 | | while (++first != last) { |
7709 | | auto&& val = *first; |
7710 | | if (nano::invoke(comp, nano::invoke(proj, val), |
7711 | | nano::invoke(proj, result))) { |
7712 | | result = std::forward<decltype(val)>(val); |
7713 | | } |
7714 | | } |
7715 | | |
7716 | | return result; |
7717 | | } |
7718 | | |
7719 | | public: |
7720 | | template <typename T, |
7721 | | typename Comp = ranges::less, |
7722 | | typename Proj = identity> |
7723 | | constexpr std::enable_if_t< |
7724 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
7725 | | const T&> |
7726 | | operator()(const T& a, |
7727 | | const T& b, |
7728 | | Comp comp = Comp{}, |
7729 | | Proj proj = Proj{}) const |
7730 | 0 | { |
7731 | 0 | return nano::invoke(comp, nano::invoke(proj, b), |
7732 | 0 | nano::invoke(proj, a)) |
7733 | 0 | ? b |
7734 | 0 | : a; |
7735 | 0 | } |
7736 | | |
7737 | | template <typename T, |
7738 | | typename Comp = ranges::less, |
7739 | | typename Proj = identity> |
7740 | | constexpr std::enable_if_t< |
7741 | | copyable<T> && |
7742 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
7743 | | T> |
7744 | | operator()(std::initializer_list<T> rng, |
7745 | | Comp comp = Comp{}, |
7746 | | Proj proj = Proj{}) const |
7747 | | { |
7748 | | return min_fn::impl(rng, comp, proj); |
7749 | | } |
7750 | | |
7751 | | template <typename Rng, |
7752 | | typename Comp = ranges::less, |
7753 | | typename Proj = identity> |
7754 | | constexpr std::enable_if_t< |
7755 | | input_range<Rng> && copyable<iter_value_t<iterator_t<Rng>>> && |
7756 | | indirect_strict_weak_order<Comp, |
7757 | | projected<iterator_t<Rng>, Proj>>, |
7758 | | range_value_t<Rng>> |
7759 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
7760 | | { |
7761 | | return min_fn::impl(std::forward<Rng>(rng), comp, proj); |
7762 | | } |
7763 | | }; |
7764 | | |
7765 | | } // namespace detail |
7766 | | |
7767 | | NANO_INLINE_VAR(detail::min_fn, min) |
7768 | | |
7769 | | NANO_END_NAMESPACE |
7770 | | |
7771 | | #endif |
7772 | | |
7773 | | // nanorange/algorithm/move.hpp |
7774 | | // |
7775 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7776 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7777 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7778 | | |
7779 | | #ifndef NANORANGE_ALGORITHM_MOVE_HPP_INCLUDED |
7780 | | #define NANORANGE_ALGORITHM_MOVE_HPP_INCLUDED |
7781 | | |
7782 | | NANO_BEGIN_NAMESPACE |
7783 | | |
7784 | | template <typename I, typename O> |
7785 | | using move_result = in_out_result<I, O>; |
7786 | | |
7787 | | namespace detail { |
7788 | | |
7789 | | struct move_fn { |
7790 | | private: |
7791 | | template <typename I, typename S, typename O> |
7792 | | static constexpr std::enable_if_t<sized_sentinel_for<S, I>, |
7793 | | move_result<I, O>> |
7794 | | impl(I first, S last, O result, priority_tag<1>) |
7795 | | { |
7796 | | const auto dist = last - first; |
7797 | | |
7798 | | for (iter_difference_t<I> i{0}; i < dist; i++) { |
7799 | | *result = nano::iter_move(first); |
7800 | | ++first; |
7801 | | ++result; |
7802 | | } |
7803 | | |
7804 | | return {std::move(first), std::move(result)}; |
7805 | | } |
7806 | | |
7807 | | template <typename I, typename S, typename O> |
7808 | | static constexpr move_result<I, O> impl(I first, |
7809 | | S last, |
7810 | | O result, |
7811 | | priority_tag<0>) |
7812 | | { |
7813 | | while (first != last) { |
7814 | | *result = nano::iter_move(first); |
7815 | | ++first; |
7816 | | ++result; |
7817 | | } |
7818 | | |
7819 | | return {std::move(first), std::move(result)}; |
7820 | | } |
7821 | | |
7822 | | public: |
7823 | | template <typename I, typename S, typename O> |
7824 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
7825 | | weakly_incrementable<O> && |
7826 | | indirectly_movable<I, O>, |
7827 | | move_result<I, O>> |
7828 | | operator()(I first, S last, O result) const |
7829 | | { |
7830 | | return move_fn::impl(std::move(first), std::move(last), |
7831 | | std::move(result), priority_tag<1>{}); |
7832 | | } |
7833 | | |
7834 | | template <typename Rng, typename O> |
7835 | | constexpr std::enable_if_t<input_range<Rng> && |
7836 | | weakly_incrementable<O> && |
7837 | | indirectly_movable<iterator_t<Rng>, O>, |
7838 | | move_result<borrowed_iterator_t<Rng>, O>> |
7839 | | operator()(Rng&& rng, O result) const |
7840 | | { |
7841 | | return move_fn::impl(nano::begin(rng), nano::end(rng), |
7842 | | std::move(result), priority_tag<1>{}); |
7843 | | } |
7844 | | }; |
7845 | | |
7846 | | } // namespace detail |
7847 | | |
7848 | | NANO_INLINE_VAR(detail::move_fn, move) |
7849 | | |
7850 | | template <typename I, typename O> |
7851 | | using move_backward_result = in_out_result<I, O>; |
7852 | | |
7853 | | namespace detail { |
7854 | | |
7855 | | struct move_backward_fn { |
7856 | | private: |
7857 | | template <typename I, typename O> |
7858 | | static constexpr move_backward_result<I, O> impl(I first, |
7859 | | I last, |
7860 | | O result) |
7861 | | { |
7862 | | auto it = last; |
7863 | | |
7864 | | while (it != first) { |
7865 | | *--result = nano::iter_move(--it); |
7866 | | } |
7867 | | |
7868 | | return {std::move(last), std::move(result)}; |
7869 | | } |
7870 | | |
7871 | | template <typename I, typename S, typename O> |
7872 | | static constexpr std::enable_if_t<!same_as<I, S>, |
7873 | | move_backward_result<I, O>> |
7874 | | impl(I first, S sent, O result) |
7875 | | { |
7876 | | I last = nano::next(first, sent); |
7877 | | return impl(std::move(first), std::move(last), std::move(result)); |
7878 | | } |
7879 | | |
7880 | | public: |
7881 | | template <typename I, typename S, typename O> |
7882 | | constexpr std::enable_if_t< |
7883 | | bidirectional_iterator<I> && sentinel_for<S, I> && |
7884 | | bidirectional_iterator<O> && indirectly_movable<I, O>, |
7885 | | move_backward_result<I, O>> |
7886 | | operator()(I first, S last, O result) const |
7887 | | { |
7888 | | return move_backward_fn::impl(std::move(first), std::move(last), |
7889 | | std::move(result)); |
7890 | | } |
7891 | | |
7892 | | template <typename Rng, typename O> |
7893 | | constexpr std::enable_if_t< |
7894 | | bidirectional_range<Rng> && bidirectional_iterator<O> && |
7895 | | indirectly_movable<iterator_t<Rng>, O>, |
7896 | | move_backward_result<borrowed_iterator_t<Rng>, O>> |
7897 | | operator()(Rng&& rng, O result) const |
7898 | | { |
7899 | | return move_backward_fn::impl(nano::begin(rng), nano::end(rng), |
7900 | | std::move(result)); |
7901 | | } |
7902 | | }; |
7903 | | |
7904 | | } // namespace detail |
7905 | | |
7906 | | NANO_INLINE_VAR(detail::move_backward_fn, move_backward) |
7907 | | |
7908 | | NANO_END_NAMESPACE |
7909 | | |
7910 | | #endif |
7911 | | |
7912 | | // nanorange/algorithm/rotate.hpp |
7913 | | // |
7914 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7915 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7916 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7917 | | |
7918 | | #ifndef NANORANGE_ALGORITHM_ROTATE_HPP_INCLUDED |
7919 | | #define NANORANGE_ALGORITHM_ROTATE_HPP_INCLUDED |
7920 | | |
7921 | | // nanorange/algorithm/swap_ranges.hpp |
7922 | | // |
7923 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
7924 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7925 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7926 | | |
7927 | | #ifndef NANORANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED |
7928 | | #define NANORANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED |
7929 | | |
7930 | | NANO_BEGIN_NAMESPACE |
7931 | | |
7932 | | template <typename I1, typename I2> |
7933 | | using swap_ranges_result = in_in_result<I1, I2>; |
7934 | | |
7935 | | namespace detail { |
7936 | | |
7937 | | struct swap_ranges_fn { |
7938 | | template <typename I1, typename S1, typename I2, typename S2> |
7939 | | static constexpr swap_ranges_result<I1, I2> impl4(I1 first1, |
7940 | | S1 last1, |
7941 | | I2 first2, |
7942 | | S2 last2) |
7943 | | { |
7944 | | while (first1 != last1 && first2 != last2) { |
7945 | | nano::iter_swap(first1, first2); |
7946 | | ++first1; |
7947 | | ++first2; |
7948 | | } |
7949 | | return {std::move(first1), std::move(first2)}; |
7950 | | } |
7951 | | |
7952 | | template <typename I1, typename S1, typename I2> |
7953 | | static constexpr swap_ranges_result<I1, I2> impl3(I1 first1, |
7954 | | S1 last1, |
7955 | | I2 first2) |
7956 | | { |
7957 | | while (first1 != last1) { |
7958 | | nano::iter_swap(first1, first2); |
7959 | | ++first1; |
7960 | | ++first2; |
7961 | | } |
7962 | | return {std::move(first1), std::move(first2)}; |
7963 | | } |
7964 | | |
7965 | | public: |
7966 | | template <typename I1, typename S1, typename I2, typename S2> |
7967 | | constexpr std::enable_if_t< |
7968 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
7969 | | forward_iterator<I2> && sentinel_for<S2, I2> && |
7970 | | indirectly_swappable<I1, I2>, |
7971 | | swap_ranges_result<I1, I2>> |
7972 | | operator()(I1 first1, S1 last1, I2 first2, S2 last2) const |
7973 | | { |
7974 | | return swap_ranges_fn::impl4(std::move(first1), std::move(last1), |
7975 | | std::move(first2), std::move(last2)); |
7976 | | } |
7977 | | |
7978 | | template <typename I1, typename S1, typename I2> |
7979 | | NANO_DEPRECATED constexpr std::enable_if_t< |
7980 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
7981 | | forward_iterator<I2> && indirectly_swappable<I1, I2>, |
7982 | | swap_ranges_result<I1, I2>> |
7983 | | operator()(I1 first1, S1 last1, I2 first2) const |
7984 | | { |
7985 | | return swap_ranges_fn::impl3(std::move(first1), std::move(last1), |
7986 | | std::move(first2)); |
7987 | | } |
7988 | | |
7989 | | template <typename Rng1, typename Rng2> |
7990 | | constexpr std::enable_if_t< |
7991 | | forward_range<Rng1> && forward_range<Rng2> && |
7992 | | indirectly_swappable<iterator_t<Rng1>, iterator_t<Rng2>>, |
7993 | | swap_ranges_result<borrowed_iterator_t<Rng1>, |
7994 | | borrowed_iterator_t<Rng2>>> |
7995 | | operator()(Rng1&& rng1, Rng2&& rng2) const |
7996 | | { |
7997 | | return swap_ranges_fn::impl4(nano::begin(rng1), nano::end(rng1), |
7998 | | nano::begin(rng2), nano::end(rng2)); |
7999 | | } |
8000 | | |
8001 | | template <typename Rng1, typename I2> |
8002 | | NANO_DEPRECATED constexpr std::enable_if_t< |
8003 | | forward_range<Rng1> && forward_iterator<I2> && |
8004 | | indirectly_swappable<iterator_t<Rng1>, I2>, |
8005 | | swap_ranges_result<borrowed_iterator_t<Rng1>, I2>> |
8006 | | operator()(Rng1&& rng1, I2 first2) const |
8007 | | { |
8008 | | return swap_ranges_fn::impl3(nano::begin(rng1), nano::end(rng1), |
8009 | | std::move(first2)); |
8010 | | } |
8011 | | }; |
8012 | | |
8013 | | } // namespace detail |
8014 | | |
8015 | | NANO_INLINE_VAR(detail::swap_ranges_fn, swap_ranges) |
8016 | | |
8017 | | NANO_END_NAMESPACE |
8018 | | |
8019 | | #endif |
8020 | | |
8021 | | // nanorange/iterator/unreachable.hpp |
8022 | | // |
8023 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8024 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8025 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8026 | | |
8027 | | #ifndef NANORANGE_ITERATOR_UNREACHABLE_HPP_INCLUDED |
8028 | | #define NANORANGE_ITERATOR_UNREACHABLE_HPP_INCLUDED |
8029 | | |
8030 | | NANO_BEGIN_NAMESPACE |
8031 | | |
8032 | | // [range.unreachable.sentinels] |
8033 | | |
8034 | | struct unreachable_sentinel_t { |
8035 | | template <typename I> |
8036 | | friend constexpr std::enable_if_t<weakly_incrementable<I>, bool> operator==( |
8037 | | const I&, |
8038 | | unreachable_sentinel_t) noexcept |
8039 | | { |
8040 | | return false; |
8041 | | } |
8042 | | |
8043 | | template <typename I> |
8044 | | friend constexpr std::enable_if_t<weakly_incrementable<I>, bool> operator==( |
8045 | | unreachable_sentinel_t, |
8046 | | const I&) noexcept |
8047 | | { |
8048 | | return false; |
8049 | | } |
8050 | | |
8051 | | template <typename I> |
8052 | | friend constexpr std::enable_if_t<weakly_incrementable<I>, bool> operator!=( |
8053 | | const I&, |
8054 | | unreachable_sentinel_t) noexcept |
8055 | | { |
8056 | | return true; |
8057 | | } |
8058 | | |
8059 | | template <typename I> |
8060 | | friend constexpr std::enable_if_t<weakly_incrementable<I>, bool> operator!=( |
8061 | | unreachable_sentinel_t, |
8062 | | const I&) noexcept |
8063 | | { |
8064 | | return true; |
8065 | | } |
8066 | | }; |
8067 | | |
8068 | | inline constexpr unreachable_sentinel_t unreachable_sentinel{}; |
8069 | | |
8070 | | NANO_END_NAMESPACE |
8071 | | |
8072 | | #endif |
8073 | | |
8074 | | NANO_BEGIN_NAMESPACE |
8075 | | |
8076 | | namespace detail { |
8077 | | |
8078 | | struct rotate_fn { |
8079 | | private: |
8080 | | template <typename I, typename S> |
8081 | | static constexpr subrange<I> do_rotate_one_left(I first, S last) |
8082 | | { |
8083 | | // Stash the first element and move everything one place |
8084 | | iter_value_t<I> val = nano::iter_move(first); |
8085 | | auto ret = nano::move(nano::next(first), std::move(last), first); |
8086 | | *ret.out = std::move(val); |
8087 | | return {std::move(ret.out), std::move(ret.in)}; |
8088 | | } |
8089 | | |
8090 | | template <typename I> |
8091 | | static constexpr subrange<I> do_rotate_one_right(I first, I middle) |
8092 | | { |
8093 | | I last = nano::next(middle); |
8094 | | iter_value_t<I> val = nano::iter_move(middle); |
8095 | | nano::move_backward(first, middle, last); |
8096 | | *first = std::move(val); |
8097 | | return {std::move(++first), std::move(last)}; |
8098 | | } |
8099 | | |
8100 | | template <typename I, typename S> |
8101 | | static constexpr std::enable_if_t<random_access_iterator<I> && |
8102 | | sized_sentinel_for<S, I>, |
8103 | | subrange<I>> |
8104 | | do_rotate(I first, I middle, S last, priority_tag<2>) |
8105 | | { |
8106 | | constexpr bool is_tma = |
8107 | | std::is_trivially_move_assignable<iter_value_t<I>>::value; |
8108 | | |
8109 | | auto i = nano::distance(first, middle); |
8110 | | auto j = nano::distance(first, last) - i; |
8111 | | I out = first + (last - middle); |
8112 | | |
8113 | | while (i != j) { |
8114 | | if (i > j) { |
8115 | | if (is_tma && j == 1) { |
8116 | | do_rotate_one_right(middle - i, middle); |
8117 | | return {std::move(out), nano::next(first, last)}; |
8118 | | } |
8119 | | nano::swap_ranges(middle - i, unreachable_sentinel, middle, |
8120 | | middle + j); |
8121 | | i -= j; |
8122 | | } |
8123 | | else { |
8124 | | if (is_tma && i == 1) { |
8125 | | do_rotate_one_left(middle - i, middle + j); |
8126 | | return {std::move(out), nano::next(first, last)}; |
8127 | | } |
8128 | | nano::swap_ranges(middle - i, middle, middle + j - i, |
8129 | | unreachable_sentinel); |
8130 | | j -= i; |
8131 | | } |
8132 | | } |
8133 | | nano::swap_ranges(middle - i, middle, middle, unreachable_sentinel); |
8134 | | |
8135 | | return {std::move(out), nano::next(first, last)}; |
8136 | | } |
8137 | | |
8138 | | template <typename I, typename S> |
8139 | | static constexpr std::enable_if_t<bidirectional_iterator<I>, |
8140 | | subrange<I>> |
8141 | | do_rotate(I first, I middle, S last, priority_tag<1>) |
8142 | | { |
8143 | | if (std::is_trivially_move_assignable<iter_value_t<I>>::value && |
8144 | | nano::next(middle) == last) { |
8145 | | return do_rotate_one_right(std::move(first), std::move(middle)); |
8146 | | } |
8147 | | |
8148 | | return do_rotate(std::move(first), std::move(middle), |
8149 | | std::move(last), priority_tag<0>{}); |
8150 | | } |
8151 | | |
8152 | | template <typename I, typename S> |
8153 | | static constexpr subrange<I> do_rotate(I first, |
8154 | | I middle, |
8155 | | S last, |
8156 | | priority_tag<0>) |
8157 | | { |
8158 | | if (std::is_trivially_move_assignable<iter_value_t<I>>::value && |
8159 | | nano::next(first) == middle) { |
8160 | | return do_rotate_one_left(std::move(first), std::move(last)); |
8161 | | } |
8162 | | |
8163 | | if (sized_sentinel_for<I, I> && sized_sentinel_for<S, I> && |
8164 | | nano::distance(first, middle) == nano::distance(middle, last)) { |
8165 | | auto ret = nano::swap_ranges(first, middle, middle, |
8166 | | unreachable_sentinel); |
8167 | | return {std::move(ret.in1), std::move(ret.in2)}; |
8168 | | } |
8169 | | |
8170 | | I next = middle; |
8171 | | |
8172 | | do { |
8173 | | nano::iter_swap(first++, next++); |
8174 | | if (first == middle) { |
8175 | | middle = next; |
8176 | | } |
8177 | | } while (next != last); |
8178 | | |
8179 | | I ret = first; |
8180 | | next = middle; |
8181 | | |
8182 | | while (next != last) { |
8183 | | nano::iter_swap(first++, next++); |
8184 | | if (first == middle) { |
8185 | | middle = next; |
8186 | | } |
8187 | | else if (next == last) { |
8188 | | next = middle; |
8189 | | } |
8190 | | } |
8191 | | |
8192 | | return {std::move(ret), std::move(next)}; |
8193 | | } |
8194 | | |
8195 | | template <typename I, typename S> |
8196 | | static constexpr subrange<I> impl(I first, I middle, S last) |
8197 | | { |
8198 | | if (first == middle) { |
8199 | | auto ret = nano::next(first, last); |
8200 | | return {ret, ret}; |
8201 | | } |
8202 | | if (middle == last) { |
8203 | | return {first, middle}; |
8204 | | } |
8205 | | |
8206 | | return do_rotate(std::move(first), std::move(middle), |
8207 | | std::move(last), priority_tag<2>{}); |
8208 | | } |
8209 | | |
8210 | | public: |
8211 | | template <typename I, typename S> |
8212 | | constexpr std::enable_if_t<forward_iterator<I> && sentinel_for<S, I> && |
8213 | | permutable<I>, |
8214 | | subrange<I>> |
8215 | | operator()(I first, I middle, S last) const |
8216 | | { |
8217 | | return rotate_fn::impl(std::move(first), std::move(middle), |
8218 | | std::move(last)); |
8219 | | } |
8220 | | |
8221 | | template <typename Rng> |
8222 | | constexpr std::enable_if_t<forward_range<Rng> && |
8223 | | permutable<iterator_t<Rng>>, |
8224 | | borrowed_subrange_t<Rng>> |
8225 | | operator()(Rng&& rng, iterator_t<Rng> middle) const |
8226 | | { |
8227 | | return rotate_fn::impl(nano::begin(rng), std::move(middle), |
8228 | | nano::end(rng)); |
8229 | | } |
8230 | | }; |
8231 | | |
8232 | | } // namespace detail |
8233 | | |
8234 | | NANO_INLINE_VAR(detail::rotate_fn, rotate) |
8235 | | |
8236 | | NANO_END_NAMESPACE |
8237 | | |
8238 | | #endif |
8239 | | |
8240 | | // nanorange/detail/memory/temporary_vector.hpp |
8241 | | // |
8242 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
8243 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8244 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8245 | | |
8246 | | #ifndef NANORANGE_DETAIL_MEMORY_TEMPORARY_VECTOR_HPP_INCLUDED |
8247 | | #define NANORANGE_DETAIL_MEMORY_TEMPORARY_VECTOR_HPP_INCLUDED |
8248 | | |
8249 | | // nanorange/memory/destroy.hpp |
8250 | | // |
8251 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8252 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8253 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8254 | | |
8255 | | #ifndef NANORANGE_MEMORY_DESTROY_HPP_INCLUDED |
8256 | | #define NANORANGE_MEMORY_DESTROY_HPP_INCLUDED |
8257 | | |
8258 | | // nanorange/detail/memory/concepts.hpp |
8259 | | // |
8260 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8261 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8262 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8263 | | |
8264 | | #ifndef NANORANGE_DETAIL_MEMORY_CONCEPTS_HPP_INCLUDED |
8265 | | #define NANORANGE_DETAIL_MEMORY_CONCEPTS_HPP_INCLUDED |
8266 | | |
8267 | | NANO_BEGIN_NAMESPACE |
8268 | | |
8269 | | namespace detail { |
8270 | | |
8271 | | struct no_throw_input_iterator_concept { |
8272 | | template <typename> |
8273 | | static auto test(long) -> std::false_type; |
8274 | | |
8275 | | template <typename I> |
8276 | | static auto test(int) -> std::enable_if_t< |
8277 | | input_iterator<I> && |
8278 | | std::is_lvalue_reference<iter_reference_t<I>>::value && |
8279 | | same_as<remove_cvref_t<iter_reference_t<I>>, iter_value_t<I>>, |
8280 | | std::true_type>; |
8281 | | }; |
8282 | | |
8283 | | template <typename I> |
8284 | | NANO_CONCEPT no_throw_input_iterator = |
8285 | | decltype(no_throw_input_iterator_concept::test<I>(0))::value; |
8286 | | |
8287 | | template <typename S, typename I> |
8288 | | NANO_CONCEPT no_throw_sentinel = sentinel_for<S, I>; |
8289 | | |
8290 | | struct no_throw_input_range_concept { |
8291 | | template <typename> |
8292 | | static auto test(long) -> std::false_type; |
8293 | | |
8294 | | template <typename R> |
8295 | | static auto test(int) -> std::enable_if_t< |
8296 | | range<R> && no_throw_input_iterator<iterator_t<R>> && |
8297 | | no_throw_sentinel<sentinel_t<R>, iterator_t<R>>, |
8298 | | std::true_type>; |
8299 | | }; |
8300 | | |
8301 | | template <typename R> |
8302 | | NANO_CONCEPT no_throw_input_range = |
8303 | | decltype(no_throw_input_range_concept::test<R>(0))::value; |
8304 | | |
8305 | | template <typename I> |
8306 | | NANO_CONCEPT no_throw_forward_iterator = |
8307 | | no_throw_input_iterator<I> && forward_iterator<I> && |
8308 | | no_throw_sentinel<I, I>; |
8309 | | |
8310 | | struct no_throw_forward_range_concept { |
8311 | | template <typename> |
8312 | | static auto test(long) -> std::false_type; |
8313 | | |
8314 | | template <typename R> |
8315 | | static auto test(int) |
8316 | | -> std::enable_if_t<no_throw_input_range<R> && |
8317 | | no_throw_forward_iterator<iterator_t<R>>, |
8318 | | std::true_type>; |
8319 | | }; |
8320 | | |
8321 | | template <typename R> |
8322 | | NANO_CONCEPT no_throw_forward_range = |
8323 | | decltype(no_throw_forward_range_concept::test<R>(0))::value; |
8324 | | |
8325 | | template <typename T> |
8326 | | void* voidify(T& ptr) noexcept |
8327 | | { |
8328 | | return const_cast<void*>( |
8329 | | static_cast<const volatile void*>(std::addressof(ptr))); |
8330 | | } |
8331 | | |
8332 | | } // namespace detail |
8333 | | |
8334 | | NANO_END_NAMESPACE |
8335 | | |
8336 | | #endif |
8337 | | |
8338 | | // nanorange/iterator/counted_iterator.hpp |
8339 | | // |
8340 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8341 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8342 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8343 | | |
8344 | | #ifndef NANORANGE_ITERATOR_COUNTED_ITERATOR_HPP_INCLUDED |
8345 | | #define NANORANGE_ITERATOR_COUNTED_ITERATOR_HPP_INCLUDED |
8346 | | |
8347 | | // nanorange/iterator/default_sentinel.hpp |
8348 | | // |
8349 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8350 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8351 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8352 | | |
8353 | | #ifndef NANORANGE_ITERATOR_DEFAULT_SENTINEL_HPP_INCLUDED |
8354 | | #define NANORANGE_ITERATOR_DEFAULT_SENTINEL_HPP_INCLUDED |
8355 | | |
8356 | | NANO_BEGIN_NAMESPACE |
8357 | | |
8358 | | struct default_sentinel_t {}; |
8359 | | |
8360 | | inline constexpr default_sentinel_t default_sentinel{}; |
8361 | | |
8362 | | NANO_END_NAMESPACE |
8363 | | |
8364 | | #endif |
8365 | | |
8366 | | NANO_BEGIN_NAMESPACE |
8367 | | |
8368 | | namespace counted_iterator_ { |
8369 | | |
8370 | | template <typename I> |
8371 | | class counted_iterator { |
8372 | | static_assert(input_or_output_iterator<I>, ""); |
8373 | | |
8374 | | template <typename I2> |
8375 | | friend class counted_iterator; |
8376 | | |
8377 | | public: |
8378 | | using iterator = I; |
8379 | | using difference_type = iter_difference_t<I>; |
8380 | | |
8381 | | constexpr counted_iterator() = default; |
8382 | | |
8383 | | constexpr counted_iterator(I x, iter_difference_t<I> n) |
8384 | | : current_(x), cnt_(n) |
8385 | | { |
8386 | | } |
8387 | | |
8388 | | template <typename I2, std::enable_if_t<convertible_to<I2, I>, int> = 0> |
8389 | | constexpr counted_iterator(const counted_iterator<I2>& i) |
8390 | | : current_(i.current_), cnt_(i.cnt_) |
8391 | | { |
8392 | | } |
8393 | | |
8394 | | template <typename I2> |
8395 | | constexpr auto operator=(const counted_iterator<I2>& i) |
8396 | | -> std::enable_if_t<convertible_to<I2, I>, counted_iterator&> |
8397 | | { |
8398 | | current_ = i.current_; |
8399 | | cnt_ = i.cnt_; |
8400 | | return *this; |
8401 | | } |
8402 | | |
8403 | | constexpr I base() const |
8404 | | { |
8405 | | return current_; |
8406 | | } |
8407 | | |
8408 | | constexpr iter_difference_t<I> count() const |
8409 | | { |
8410 | | return cnt_; |
8411 | | } |
8412 | | |
8413 | | constexpr decltype(auto) operator*() |
8414 | | { |
8415 | | return *current_; |
8416 | | } |
8417 | | |
8418 | | template <typename II = I, |
8419 | | std::enable_if_t<detail::dereferenceable<const II>, int> = 0> |
8420 | | constexpr decltype(auto) operator*() const |
8421 | | { |
8422 | | return *current_; |
8423 | | } |
8424 | | |
8425 | | constexpr counted_iterator& operator++() |
8426 | | { |
8427 | | ++current_; |
8428 | | --cnt_; |
8429 | | return *this; |
8430 | | } |
8431 | | |
8432 | | template <typename II = I, |
8433 | | std::enable_if_t<!forward_iterator<II>, int> = 0> |
8434 | | decltype(auto) operator++(int) |
8435 | | { |
8436 | | --cnt_; |
8437 | | try { |
8438 | | return current_++; |
8439 | | } |
8440 | | catch (...) { |
8441 | | ++cnt_; |
8442 | | throw; |
8443 | | } |
8444 | | } |
8445 | | |
8446 | | template <typename II = I> |
8447 | | constexpr auto operator++(int) |
8448 | | -> std::enable_if_t<forward_iterator<II>, counted_iterator> |
8449 | | { |
8450 | | auto tmp = *this; |
8451 | | ++*this; |
8452 | | return tmp; |
8453 | | } |
8454 | | |
8455 | | template <typename II = I> |
8456 | | constexpr auto operator--() |
8457 | | -> std::enable_if_t<bidirectional_iterator<II>, counted_iterator&> |
8458 | | { |
8459 | | --current_; |
8460 | | ++cnt_; |
8461 | | return *this; |
8462 | | } |
8463 | | |
8464 | | template <typename II = I> |
8465 | | constexpr auto operator--(int) |
8466 | | -> std::enable_if_t<bidirectional_iterator<II>, counted_iterator> |
8467 | | { |
8468 | | auto tmp = *this; |
8469 | | --*this; |
8470 | | return tmp; |
8471 | | } |
8472 | | |
8473 | | template <typename II = I> |
8474 | | constexpr auto operator+(difference_type n) const |
8475 | | -> std::enable_if_t<random_access_iterator<II>, counted_iterator> |
8476 | | { |
8477 | | return counted_iterator(current_ + n, cnt_ - n); |
8478 | | } |
8479 | | |
8480 | | template <typename II = I, |
8481 | | std::enable_if_t<random_access_iterator<II>, int> = 0> |
8482 | | friend constexpr counted_iterator operator+( |
8483 | | iter_difference_t<II> n, |
8484 | | const counted_iterator<II>& x) |
8485 | | { |
8486 | | return x + n; |
8487 | | } |
8488 | | |
8489 | | template <typename II = I> |
8490 | | constexpr auto operator+=(difference_type n) |
8491 | | -> std::enable_if_t<random_access_iterator<II>, counted_iterator&> |
8492 | | { |
8493 | | current_ += n; |
8494 | | cnt_ -= n; |
8495 | | return *this; |
8496 | | } |
8497 | | |
8498 | | template <typename II = I> |
8499 | | constexpr auto operator-(difference_type n) const |
8500 | | -> std::enable_if_t<random_access_iterator<II>, counted_iterator> |
8501 | | { |
8502 | | return counted_iterator(current_ - n, cnt_ + n); |
8503 | | } |
8504 | | |
8505 | | template <typename II = I, |
8506 | | std::enable_if_t<random_access_iterator<II>, int> = 0> |
8507 | | constexpr decltype(auto) operator[](difference_type n) const |
8508 | | { |
8509 | | return current_[n]; |
8510 | | } |
8511 | | |
8512 | | template <typename I2> |
8513 | | friend constexpr auto operator==(const counted_iterator& x, |
8514 | | const counted_iterator<I2>& y) |
8515 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8516 | | { |
8517 | | return x.count() == y.count(); |
8518 | | } |
8519 | | |
8520 | | friend constexpr bool operator==(const counted_iterator& x, |
8521 | | default_sentinel_t) |
8522 | | { |
8523 | | return x.count() == 0; |
8524 | | } |
8525 | | |
8526 | | friend constexpr bool operator==(default_sentinel_t, |
8527 | | const counted_iterator& x) |
8528 | | { |
8529 | | return x.count() == 0; |
8530 | | } |
8531 | | |
8532 | | template <typename I2> |
8533 | | friend constexpr auto operator!=(const counted_iterator& x, |
8534 | | const counted_iterator<I2>& y) |
8535 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8536 | | { |
8537 | | return !(x == y); |
8538 | | } |
8539 | | |
8540 | | friend constexpr bool operator!=(const counted_iterator& x, |
8541 | | default_sentinel_t y) |
8542 | | { |
8543 | | return !(x == y); |
8544 | | } |
8545 | | |
8546 | | friend constexpr bool operator!=(default_sentinel_t x, |
8547 | | const counted_iterator& y) |
8548 | | { |
8549 | | return !(x == y); |
8550 | | } |
8551 | | |
8552 | | template <typename I2> |
8553 | | friend constexpr auto operator<(const counted_iterator& x, |
8554 | | const counted_iterator<I2>& y) |
8555 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8556 | | { |
8557 | | return y.count() < x.count(); |
8558 | | } |
8559 | | |
8560 | | template <typename I2> |
8561 | | friend constexpr auto operator>(const counted_iterator& x, |
8562 | | const counted_iterator<I2>& y) |
8563 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8564 | | { |
8565 | | return y < x; |
8566 | | } |
8567 | | |
8568 | | template <typename I2> |
8569 | | friend constexpr auto operator<=(const counted_iterator& x, |
8570 | | const counted_iterator<I2>& y) |
8571 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8572 | | { |
8573 | | return !(y < x); |
8574 | | } |
8575 | | |
8576 | | template <typename I2> |
8577 | | friend constexpr auto operator>=(const counted_iterator& x, |
8578 | | const counted_iterator<I2>& y) |
8579 | | -> std::enable_if_t<common_with<I2, I>, bool> |
8580 | | { |
8581 | | return !(x < y); |
8582 | | } |
8583 | | |
8584 | | template <typename I2> |
8585 | | friend constexpr auto operator-(const counted_iterator& x, |
8586 | | const counted_iterator<I2>& y) |
8587 | | -> std::enable_if_t<common_with<I2, I>, iter_difference_t<I2>> |
8588 | | { |
8589 | | return y.count() - x.count(); |
8590 | | } |
8591 | | |
8592 | | friend constexpr iter_difference_t<I> operator-( |
8593 | | const counted_iterator& x, |
8594 | | default_sentinel_t) |
8595 | | { |
8596 | | return -x.cnt_; |
8597 | | } |
8598 | | |
8599 | | friend constexpr iter_difference_t<I> operator-( |
8600 | | default_sentinel_t, |
8601 | | const counted_iterator& y) |
8602 | | { |
8603 | | return y.cnt_; |
8604 | | } |
8605 | | |
8606 | | template <typename II = I> |
8607 | | constexpr auto operator-=(difference_type n) |
8608 | | -> std::enable_if_t<random_access_iterator<II>, counted_iterator&> |
8609 | | { |
8610 | | current_ -= n; |
8611 | | cnt_ += n; |
8612 | | return *this; |
8613 | | } |
8614 | | |
8615 | | #ifndef _MSC_VER |
8616 | | // FIXME MSVC: If this is a template, MSVC can't find it via ADL for |
8617 | | // some reason Making it a non-template doesn't lose much other than the |
8618 | | // InputIterator guard |
8619 | | template <typename II = I, |
8620 | | std::enable_if_t<input_iterator<II>, int> = 0> |
8621 | | #endif |
8622 | | friend constexpr iter_rvalue_reference_t<I> |
8623 | | iter_move(const counted_iterator& i) noexcept( |
8624 | | noexcept(ranges::iter_move(i.current_))) |
8625 | | { |
8626 | | return ranges::iter_move(i.current_); |
8627 | | } |
8628 | | |
8629 | | template <typename I2> |
8630 | | friend constexpr auto iter_swap( |
8631 | | const counted_iterator<I>& x, |
8632 | | const counted_iterator<I2>& |
8633 | | y) noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) |
8634 | | -> std::enable_if_t<indirectly_swappable<I2, I>> |
8635 | | { |
8636 | | ranges::iter_swap(x.current_, y.current_); |
8637 | | } |
8638 | | |
8639 | | private: |
8640 | | I current_{}; |
8641 | | iter_difference_t<I> cnt_{0}; |
8642 | | }; |
8643 | | |
8644 | | } // namespace counted_iterator_ |
8645 | | |
8646 | | using counted_iterator_::counted_iterator; |
8647 | | |
8648 | | namespace detail { |
8649 | | |
8650 | | template <typename I, typename = void> |
8651 | | struct counted_iterator_readable_traits_helper {}; |
8652 | | |
8653 | | template <typename I> |
8654 | | struct counted_iterator_readable_traits_helper< |
8655 | | I, |
8656 | | std::enable_if_t<readable<I>>> { |
8657 | | using value_type = iter_value_t<I>; |
8658 | | }; |
8659 | | |
8660 | | template <typename I, typename = void> |
8661 | | struct counted_iterator_category_helper {}; |
8662 | | |
8663 | | template <typename I> |
8664 | | struct counted_iterator_category_helper< |
8665 | | I, |
8666 | | std::enable_if_t<input_iterator<I>>> { |
8667 | | using type = iterator_category_t<I>; |
8668 | | }; |
8669 | | |
8670 | | } // namespace detail |
8671 | | |
8672 | | template <typename I> |
8673 | | struct readable_traits<counted_iterator<I>> |
8674 | | : detail::counted_iterator_readable_traits_helper<I> {}; |
8675 | | |
8676 | | template <typename I> |
8677 | | struct iterator_category<counted_iterator<I>> |
8678 | | : detail::counted_iterator_category_helper<I> {}; |
8679 | | |
8680 | | template <typename I> |
8681 | | constexpr auto make_counted_iterator(I i, iter_difference_t<I> n) |
8682 | | -> std::enable_if_t<input_or_output_iterator<I>, counted_iterator<I>> |
8683 | | { |
8684 | | return counted_iterator<I>(std::move(i), n); |
8685 | | } |
8686 | | |
8687 | | NANO_END_NAMESPACE |
8688 | | |
8689 | | #endif |
8690 | | |
8691 | | NANO_BEGIN_NAMESPACE |
8692 | | |
8693 | | template <typename T> |
8694 | | std::enable_if_t<destructible<T>> destroy_at(T* location) noexcept |
8695 | | { |
8696 | | location->~T(); |
8697 | | } |
8698 | | |
8699 | | namespace detail { |
8700 | | |
8701 | | struct destroy_fn { |
8702 | | private: |
8703 | | template <typename I, typename S> |
8704 | | static I impl(I first, S last) noexcept |
8705 | | { |
8706 | | for (; first != last; ++first) { |
8707 | | nano::destroy_at(std::addressof(*first)); |
8708 | | } |
8709 | | return first; |
8710 | | } |
8711 | | |
8712 | | public: |
8713 | | template <typename I, typename S> |
8714 | | std::enable_if_t<no_throw_input_iterator<I> && |
8715 | | no_throw_sentinel<S, I> && |
8716 | | destructible<iter_value_t<I>>, |
8717 | | I> |
8718 | | operator()(I first, S last) const noexcept |
8719 | | { |
8720 | | return destroy_fn::impl(std::move(first), std::move(last)); |
8721 | | } |
8722 | | |
8723 | | template <typename Rng> |
8724 | | std::enable_if_t<no_throw_input_range<Rng> && |
8725 | | destructible<iter_value_t<iterator_t<Rng>>>, |
8726 | | borrowed_iterator_t<Rng>> |
8727 | | operator()(Rng&& rng) const noexcept |
8728 | | { |
8729 | | return destroy_fn::impl(nano::begin(rng), nano::end(rng)); |
8730 | | } |
8731 | | }; |
8732 | | |
8733 | | } // namespace detail |
8734 | | |
8735 | | NANO_INLINE_VAR(detail::destroy_fn, destroy) |
8736 | | |
8737 | | namespace detail { |
8738 | | |
8739 | | struct destroy_n_fn { |
8740 | | template <typename I> |
8741 | | std::enable_if_t<no_throw_input_iterator<I> && |
8742 | | destructible<iter_value_t<I>>, |
8743 | | I> |
8744 | | operator()(I first, iter_difference_t<I> n) const noexcept |
8745 | | { |
8746 | | return nano::destroy(make_counted_iterator(std::move(first), n), |
8747 | | default_sentinel) |
8748 | | .base(); |
8749 | | } |
8750 | | }; |
8751 | | |
8752 | | } // namespace detail |
8753 | | |
8754 | | NANO_INLINE_VAR(detail::destroy_n_fn, destroy_n) |
8755 | | |
8756 | | NANO_END_NAMESPACE |
8757 | | |
8758 | | #endif |
8759 | | |
8760 | | #include <cassert> |
8761 | | #include <memory> |
8762 | | #include <new> |
8763 | | |
8764 | | NANO_BEGIN_NAMESPACE |
8765 | | |
8766 | | namespace detail { |
8767 | | |
8768 | | template <typename T> |
8769 | | struct temporary_vector { |
8770 | | private: |
8771 | | struct deleter { |
8772 | | void operator()(T* ptr) const |
8773 | | { |
8774 | | ::operator delete[](ptr); |
8775 | | } |
8776 | | }; |
8777 | | |
8778 | | public: |
8779 | | temporary_vector() = default; |
8780 | | |
8781 | | explicit temporary_vector(std::size_t capacity) |
8782 | | : start_(static_cast<T*>( |
8783 | | ::operator new[](capacity * sizeof(T), std::nothrow))), |
8784 | | end_cap_(start_ ? start_.get() + capacity : nullptr) |
8785 | | { |
8786 | | } |
8787 | | |
8788 | | temporary_vector(temporary_vector&& other) noexcept |
8789 | | : start_(std::move(other.start_)), |
8790 | | end_(other.end_), |
8791 | | end_cap_(other.end_cap_) |
8792 | | { |
8793 | | other.end_ = nullptr; |
8794 | | other.end_cap_ = nullptr; |
8795 | | } |
8796 | | |
8797 | | temporary_vector& operator=(temporary_vector&& other) noexcept |
8798 | | { |
8799 | | nano::swap(start_, other.start_); |
8800 | | nano::swap(end_, other.end_); |
8801 | | nano::swap(end_cap_, other.end_cap_); |
8802 | | return *this; |
8803 | | } |
8804 | | |
8805 | | ~temporary_vector() |
8806 | | { |
8807 | | nano::destroy(begin(), end()); |
8808 | | } |
8809 | | |
8810 | | std::size_t size() const |
8811 | | { |
8812 | | return end_ - start_.get(); |
8813 | | } |
8814 | | std::size_t capacity() const |
8815 | | { |
8816 | | return end_cap_ - start_.get(); |
8817 | | } |
8818 | | [[nodiscard]] bool empty() const |
8819 | | { |
8820 | | return size() == 0; |
8821 | | } |
8822 | | |
8823 | | void push_back(const T& elem) |
8824 | | { |
8825 | | emplace_back(elem); |
8826 | | } |
8827 | | void push_back(T&& elem) |
8828 | | { |
8829 | | emplace_back(std::move(elem)); |
8830 | | } |
8831 | | |
8832 | | template <typename... Args> |
8833 | | void emplace_back(Args&&... args) |
8834 | | { |
8835 | | assert(end_ < end_cap_); |
8836 | | ::new (end_) T(std::forward<Args>(args)...); |
8837 | | ++end_; |
8838 | | } |
8839 | | |
8840 | | T* begin() |
8841 | | { |
8842 | | return start_.get(); |
8843 | | } |
8844 | | const T* begin() const |
8845 | | { |
8846 | | return start_.get(); |
8847 | | } |
8848 | | T* end() |
8849 | | { |
8850 | | return end_; |
8851 | | } |
8852 | | const T* end() const |
8853 | | { |
8854 | | return end_; |
8855 | | } |
8856 | | |
8857 | | void clear() |
8858 | | { |
8859 | | nano::destroy(begin(), end()); |
8860 | | end_ = start_.get(); |
8861 | | } |
8862 | | |
8863 | | private: |
8864 | | std::unique_ptr<T, deleter> start_{nullptr}; |
8865 | | T* end_ = start_.get(); |
8866 | | T* end_cap_ = nullptr; |
8867 | | }; |
8868 | | |
8869 | | } // namespace detail |
8870 | | |
8871 | | NANO_END_NAMESPACE |
8872 | | |
8873 | | #endif |
8874 | | |
8875 | | // nanorange/iterator/back_insert_iterator.hpp |
8876 | | // |
8877 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8878 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8879 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8880 | | |
8881 | | #ifndef NANORANGE_ITERATOR_BACK_INSERT_ITERATOR_HPP_INCLUDED |
8882 | | #define NANORANGE_ITERATOR_BACK_INSERT_ITERATOR_HPP_INCLUDED |
8883 | | |
8884 | | #include <iterator> |
8885 | | |
8886 | | NANO_BEGIN_NAMESPACE |
8887 | | |
8888 | | template <typename Container> |
8889 | | struct back_insert_iterator { |
8890 | | using container_type = Container; |
8891 | | using difference_type = std::ptrdiff_t; |
8892 | | |
8893 | | constexpr back_insert_iterator() = default; |
8894 | | |
8895 | | explicit back_insert_iterator(Container& x) : cont_(std::addressof(x)) {} |
8896 | | |
8897 | | back_insert_iterator& operator=( |
8898 | | const iter_value_t<iterator_t<Container>>& value) |
8899 | | { |
8900 | | cont_->push_back(value); |
8901 | | return *this; |
8902 | | } |
8903 | | |
8904 | | back_insert_iterator& operator=(iter_value_t<iterator_t<Container>>&& value) |
8905 | | { |
8906 | | cont_->push_back(std::move(value)); |
8907 | | return *this; |
8908 | | } |
8909 | | |
8910 | | back_insert_iterator& operator*() |
8911 | | { |
8912 | | return *this; |
8913 | | } |
8914 | | back_insert_iterator& operator++() |
8915 | | { |
8916 | | return *this; |
8917 | | } |
8918 | | back_insert_iterator& operator++(int) |
8919 | | { |
8920 | | return *this; |
8921 | | } |
8922 | | |
8923 | | private: |
8924 | | container_type* cont_ = nullptr; |
8925 | | }; |
8926 | | |
8927 | | template <typename Container> |
8928 | | back_insert_iterator<Container> back_inserter(Container& x) |
8929 | | { |
8930 | | return back_insert_iterator<Container>(x); |
8931 | | } |
8932 | | |
8933 | | NANO_END_NAMESPACE |
8934 | | |
8935 | | namespace std { |
8936 | | |
8937 | | template <typename Cont> |
8938 | | struct iterator_traits<::nano::back_insert_iterator<Cont>> { |
8939 | | using value_type = void; |
8940 | | using difference_type = ptrdiff_t; |
8941 | | using reference = void; |
8942 | | using pointer = void; |
8943 | | using iterator_category = std::output_iterator_tag; |
8944 | | }; |
8945 | | |
8946 | | } // namespace std |
8947 | | |
8948 | | #endif |
8949 | | |
8950 | | // nanorange/iterator/move_iterator.hpp |
8951 | | // |
8952 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
8953 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8954 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8955 | | |
8956 | | #ifndef NANORANGE_ITERATOR_MOVE_ITERATOR_HPP_INCLUDED |
8957 | | #define NANORANGE_ITERATOR_MOVE_ITERATOR_HPP_INCLUDED |
8958 | | |
8959 | | NANO_BEGIN_NAMESPACE |
8960 | | |
8961 | | namespace move_iterator_ { |
8962 | | |
8963 | | template <typename I> |
8964 | | class move_iterator { |
8965 | | static_assert( |
8966 | | input_iterator<I>, |
8967 | | "Template argument to move_iterator must model InputIterator"); |
8968 | | |
8969 | | template <typename I2> |
8970 | | friend class move_iterator; |
8971 | | |
8972 | | public: |
8973 | | using iterator_type = I; |
8974 | | using difference_type = iter_difference_t<I>; |
8975 | | using value_type = iter_value_t<I>; |
8976 | | using iterator_category = input_iterator_tag; |
8977 | | using reference = iter_rvalue_reference_t<I>; |
8978 | | |
8979 | | constexpr move_iterator() = default; |
8980 | | |
8981 | | explicit constexpr move_iterator(I i) : current_(std::move(i)) {} |
8982 | | |
8983 | | template <typename U, std::enable_if_t<convertible_to<U, I>, int> = 0> |
8984 | | constexpr move_iterator(const move_iterator<U>& i) |
8985 | | : current_(i.current_) |
8986 | | { |
8987 | | } |
8988 | | |
8989 | | template <typename U> |
8990 | | constexpr std::enable_if_t<convertible_to<U, I>, move_iterator&> |
8991 | | operator=(const move_iterator<U>& i) |
8992 | | { |
8993 | | current_ = i.current_; |
8994 | | return *this; |
8995 | | } |
8996 | | |
8997 | | constexpr I base() const |
8998 | | { |
8999 | | return current_; |
9000 | | } |
9001 | | |
9002 | | constexpr reference operator*() const |
9003 | | { |
9004 | | return iter_move(current_); |
9005 | | } |
9006 | | |
9007 | | constexpr move_iterator& operator++() |
9008 | | { |
9009 | | ++current_; |
9010 | | return *this; |
9011 | | } |
9012 | | |
9013 | | template <typename II = I> |
9014 | | constexpr auto operator++(int) |
9015 | | -> std::enable_if_t<!forward_iterator<II>> |
9016 | | { |
9017 | | ++current_; |
9018 | | } |
9019 | | |
9020 | | template <typename II = I> |
9021 | | constexpr auto operator++(int) |
9022 | | -> std::enable_if_t<forward_iterator<II>, move_iterator> |
9023 | | { |
9024 | | move_iterator tmp = *this; |
9025 | | ++current_; |
9026 | | return tmp; |
9027 | | } |
9028 | | |
9029 | | template <typename II = I> |
9030 | | constexpr auto operator--() |
9031 | | -> std::enable_if_t<bidirectional_iterator<II>, move_iterator&> |
9032 | | { |
9033 | | --current_; |
9034 | | return *this; |
9035 | | } |
9036 | | |
9037 | | template <typename II = I> |
9038 | | constexpr auto operator--(int) |
9039 | | -> std::enable_if_t<bidirectional_iterator<II>, move_iterator> |
9040 | | { |
9041 | | move_iterator tmp = *this; |
9042 | | --current_; |
9043 | | return tmp; |
9044 | | } |
9045 | | |
9046 | | template <typename II = I> |
9047 | | constexpr auto operator+(difference_type n) const |
9048 | | -> std::enable_if_t<random_access_iterator<II>, move_iterator> |
9049 | | { |
9050 | | return move_iterator(current_ + n); |
9051 | | } |
9052 | | |
9053 | | template <typename II = I> |
9054 | | constexpr auto operator+=(difference_type n) |
9055 | | -> std::enable_if_t<random_access_iterator<II>, move_iterator&> |
9056 | | { |
9057 | | current_ += n; |
9058 | | return *this; |
9059 | | } |
9060 | | |
9061 | | template <typename II = I> |
9062 | | constexpr auto operator-(difference_type n) const |
9063 | | -> std::enable_if_t<random_access_iterator<II>, move_iterator> |
9064 | | { |
9065 | | return move_iterator(current_ - n); |
9066 | | } |
9067 | | |
9068 | | template <typename II = I> |
9069 | | constexpr auto operator-=(difference_type n) |
9070 | | -> std::enable_if_t<random_access_iterator<II>, move_iterator&> |
9071 | | { |
9072 | | current_ -= n; |
9073 | | return *this; |
9074 | | } |
9075 | | |
9076 | | template <typename II = I> |
9077 | | constexpr auto operator[](difference_type n) const |
9078 | | -> std::enable_if_t<random_access_iterator<II>, reference> |
9079 | | // -> decltype(auto) |
9080 | | { |
9081 | | return iter_move(current_ + n); |
9082 | | } |
9083 | | |
9084 | | friend constexpr iter_rvalue_reference_t<I> |
9085 | | iter_move(const move_iterator& i) noexcept( |
9086 | | noexcept(ranges::iter_move(i.current_))) |
9087 | | { |
9088 | | return ranges::iter_move(i.current_); |
9089 | | } |
9090 | | |
9091 | | template <typename I2> |
9092 | | friend constexpr auto |
9093 | | iter_swap(const move_iterator& x, const move_iterator<I2>& y) noexcept( |
9094 | | noexcept(ranges::iter_swap(x.current_, y.current_))) |
9095 | | -> std::enable_if_t<indirectly_swappable<I2, I>> |
9096 | | { |
9097 | | ranges::iter_swap(x.current_, y.current_); |
9098 | | } |
9099 | | |
9100 | | private: |
9101 | | I current_{}; |
9102 | | }; |
9103 | | |
9104 | | template <typename I1, typename I2> |
9105 | | constexpr auto operator==(const move_iterator<I1>& x, |
9106 | | const move_iterator<I2>& y) |
9107 | | -> std::enable_if_t<equality_comparable_with<I1, I2>, bool> |
9108 | | { |
9109 | | return x.base() == y.base(); |
9110 | | } |
9111 | | |
9112 | | template <typename I1, typename I2> |
9113 | | constexpr auto operator!=(const move_iterator<I1>& x, |
9114 | | const move_iterator<I2>& y) |
9115 | | -> std::enable_if_t<equality_comparable_with<I1, I2>, bool> |
9116 | | { |
9117 | | return !(x == y); |
9118 | | } |
9119 | | |
9120 | | template <typename I1, typename I2> |
9121 | | constexpr auto operator<(const move_iterator<I1>& x, |
9122 | | const move_iterator<I2>& y) |
9123 | | -> std::enable_if_t<totally_ordered_with<I1, I2>, bool> |
9124 | | { |
9125 | | return x.base() < y.base(); |
9126 | | } |
9127 | | |
9128 | | template <typename I1, typename I2> |
9129 | | constexpr auto operator<=(const move_iterator<I1>& x, |
9130 | | const move_iterator<I2>& y) |
9131 | | -> std::enable_if_t<totally_ordered_with<I1, I2>, bool> |
9132 | | { |
9133 | | return !(y < x); |
9134 | | } |
9135 | | |
9136 | | template <typename I1, typename I2> |
9137 | | constexpr auto operator>(const move_iterator<I1>& x, |
9138 | | const move_iterator<I2>& y) |
9139 | | -> std::enable_if_t<totally_ordered_with<I1, I2>, bool> |
9140 | | { |
9141 | | return y < x; |
9142 | | } |
9143 | | |
9144 | | template <typename I1, typename I2> |
9145 | | constexpr auto operator>=(const move_iterator<I1>& x, |
9146 | | const move_iterator<I2>& y) |
9147 | | -> std::enable_if_t<totally_ordered_with<I1, I2>, bool> |
9148 | | { |
9149 | | return !(x < y); |
9150 | | } |
9151 | | |
9152 | | template <typename I1, typename I2> |
9153 | | constexpr auto operator-(const move_iterator<I1>& x, |
9154 | | const move_iterator<I2>& y) |
9155 | | -> std::enable_if_t<sized_sentinel_for<I1, I2>, iter_difference_t<I2>> |
9156 | | { |
9157 | | return x.base() - y.base(); |
9158 | | } |
9159 | | |
9160 | | template <typename I> |
9161 | | constexpr auto operator+(iter_difference_t<I> n, const move_iterator<I>& x) |
9162 | | -> std::enable_if_t<random_access_iterator<I>, move_iterator<I>> |
9163 | | { |
9164 | | return x + n; |
9165 | | } |
9166 | | |
9167 | | } // namespace move_iterator_ |
9168 | | |
9169 | | using move_iterator_::move_iterator; |
9170 | | |
9171 | | template <typename I> |
9172 | | constexpr auto make_move_iterator(I i) |
9173 | | -> std::enable_if_t<input_iterator<I>, move_iterator<I>> |
9174 | | { |
9175 | | return move_iterator<I>(std::move(i)); |
9176 | | } |
9177 | | |
9178 | | template <typename S> |
9179 | | class move_sentinel { |
9180 | | static_assert(semiregular<S>, |
9181 | | "Template argument to move_sentinel must model Semiregular"); |
9182 | | |
9183 | | public: |
9184 | | constexpr move_sentinel() = default; |
9185 | | |
9186 | | constexpr explicit move_sentinel(S s) : last_(std::move(s)) {} |
9187 | | |
9188 | | template <typename U, std::enable_if_t<convertible_to<U, S>, int> = 0> |
9189 | | constexpr move_sentinel(const move_sentinel<U>& s) : last_(s.base()) |
9190 | | { |
9191 | | } |
9192 | | |
9193 | | template <typename U> |
9194 | | constexpr auto operator=(const move_sentinel<U>& s) |
9195 | | -> std::enable_if_t<convertible_to<U, S>, move_sentinel&> |
9196 | | { |
9197 | | last_ = s.base(); |
9198 | | return *this; |
9199 | | } |
9200 | | |
9201 | | constexpr S base() const |
9202 | | { |
9203 | | return last_; |
9204 | | } |
9205 | | |
9206 | | private: |
9207 | | S last_{}; |
9208 | | }; |
9209 | | |
9210 | | template <typename I, typename S> |
9211 | | constexpr auto operator==(const move_iterator<I>& i, const move_sentinel<S>& s) |
9212 | | -> std::enable_if_t<sentinel_for<S, I>, bool> |
9213 | | { |
9214 | | return i.base() == s.base(); |
9215 | | } |
9216 | | |
9217 | | template <typename I, typename S> |
9218 | | constexpr auto operator==(const move_sentinel<S>& s, const move_iterator<I>& i) |
9219 | | -> std::enable_if_t<sentinel_for<S, I>, bool> |
9220 | | { |
9221 | | return i.base() == s.base(); |
9222 | | } |
9223 | | |
9224 | | template <typename I, typename S> |
9225 | | constexpr auto operator!=(const move_iterator<I>& i, const move_sentinel<S>& s) |
9226 | | -> std::enable_if_t<sentinel_for<S, I>, bool> |
9227 | | { |
9228 | | return !(i == s); |
9229 | | } |
9230 | | |
9231 | | template <typename I, typename S> |
9232 | | constexpr auto operator!=(const move_sentinel<S>& s, const move_iterator<I>& i) |
9233 | | -> std::enable_if_t<sentinel_for<S, I>, bool> |
9234 | | { |
9235 | | return !(i == s); |
9236 | | } |
9237 | | |
9238 | | template <typename I, typename S> |
9239 | | constexpr auto operator-(const move_sentinel<S>& s, const move_iterator<I>& i) |
9240 | | -> std::enable_if_t<sized_sentinel_for<S, I>, iter_difference_t<I>> |
9241 | | { |
9242 | | return s.base() - i.base(); |
9243 | | } |
9244 | | |
9245 | | template <typename I, typename S> |
9246 | | constexpr auto operator-(const move_iterator<I>& i, const move_sentinel<S>& s) |
9247 | | -> std::enable_if_t<sized_sentinel_for<S, I>, iter_difference_t<I>> |
9248 | | { |
9249 | | return i.base() - s.base(); |
9250 | | } |
9251 | | |
9252 | | template <typename S> |
9253 | | constexpr auto make_move_sentinel(S s) |
9254 | | -> std::enable_if_t<semiregular<S>, move_sentinel<S>> |
9255 | | { |
9256 | | return move_sentinel<S>(std::move(s)); |
9257 | | } |
9258 | | |
9259 | | NANO_END_NAMESPACE |
9260 | | |
9261 | | namespace std { |
9262 | | |
9263 | | template <typename I> |
9264 | | struct iterator_traits<::nano::move_iterator_::move_iterator<I>> { |
9265 | | using value_type = |
9266 | | typename ::nano::move_iterator_::move_iterator<I>::value_type; |
9267 | | using reference = |
9268 | | typename ::nano::move_iterator_::move_iterator<I>::reference; |
9269 | | using pointer = value_type*; |
9270 | | using difference_type = |
9271 | | typename ::nano::move_iterator_::move_iterator<I>::difference_type; |
9272 | | using iterator_category = |
9273 | | typename ::nano::move_iterator_::move_iterator< |
9274 | | I>::iterator_category; |
9275 | | }; |
9276 | | |
9277 | | } // namespace std |
9278 | | |
9279 | | #endif |
9280 | | |
9281 | | NANO_BEGIN_NAMESPACE |
9282 | | |
9283 | | namespace detail { |
9284 | | |
9285 | | struct inplace_merge_fn { |
9286 | | private: |
9287 | | friend struct stable_sort_fn; |
9288 | | |
9289 | | template <typename I, typename Pred, typename Proj> |
9290 | | static void impl_slow(I first, |
9291 | | I middle, |
9292 | | I last, |
9293 | | iter_difference_t<I> len1, |
9294 | | iter_difference_t<I> len2, |
9295 | | Pred& pred, |
9296 | | Proj& proj) |
9297 | | { |
9298 | | using dist_t = iter_difference_t<I>; |
9299 | | |
9300 | | while (true) { |
9301 | | // if middle == end, we're done |
9302 | | if (len2 == 0) { |
9303 | | return; |
9304 | | } |
9305 | | |
9306 | | // shrink [first, middle) as much as possible (with no moves), |
9307 | | // returning if it shrinks to 0 |
9308 | | for (; true; ++first, --len1) { |
9309 | | if (len1 == 0) { |
9310 | | return; |
9311 | | } |
9312 | | if (nano::invoke(pred, nano::invoke(proj, *middle), |
9313 | | nano::invoke(proj, *first))) { |
9314 | | break; |
9315 | | } |
9316 | | } |
9317 | | |
9318 | | /*if (len1 <= buf.size() || len2 <= buf.size()) { |
9319 | | impl(std::move(begin), std::move(middle), |
9320 | | std::move(end), len1, len2, buf, pred, |
9321 | | proj); return; |
9322 | | }*/ |
9323 | | |
9324 | | // first < middle < end |
9325 | | // *first > *middle |
9326 | | // partition [first, m1) [m1, middle) [middle, m2) [m2, end) |
9327 | | // such that |
9328 | | // all elements in: |
9329 | | // [first, m1) <= [middle, m2) |
9330 | | // [middle, m2) < [m1, middle) |
9331 | | // [m1, middle) <= [m2, end) |
9332 | | // and m1 or m2 is in the middle of its range |
9333 | | I m1; // "median" of [first, middle) |
9334 | | I m2; // "median" of [middle, end) |
9335 | | dist_t len11; // distance(first, m1) |
9336 | | dist_t len21; // distance(middle, m2) |
9337 | | // binary search smaller range |
9338 | | if (len1 < len2) { |
9339 | | // len >= 1, len2 >= 2 |
9340 | | len21 = len2 / 2; |
9341 | | m2 = nano::next(middle, len21); |
9342 | | m1 = nano::upper_bound(first, middle, |
9343 | | nano::invoke(proj, *m2), |
9344 | | std::ref(pred), std::ref(proj)); |
9345 | | len11 = nano::distance(first, m1); |
9346 | | } |
9347 | | else { |
9348 | | if (len1 == 1) { |
9349 | | // len1 >= len2 && len2 > 0, therefore len2 == 1 |
9350 | | // It is known *first > *middle |
9351 | | nano::iter_swap(first, middle); |
9352 | | return; |
9353 | | } |
9354 | | // len1 >= 2, len2 >= 1 |
9355 | | len11 = len1 / 2; |
9356 | | m1 = nano::next(first, len11); |
9357 | | m2 = |
9358 | | nano::lower_bound(middle, last, nano::invoke(proj, *m1), |
9359 | | std::ref(pred), std::ref(proj)); |
9360 | | len21 = nano::distance(middle, m2); |
9361 | | } |
9362 | | dist_t len12 = len1 - len11; // distance(m1, middle) |
9363 | | dist_t len22 = len2 - len21; // distance(m2, end) |
9364 | | // [first, m1) [m1, middle) [middle, m2) [m2, end) |
9365 | | // swap middle two partitions |
9366 | | middle = nano::rotate(m1, std::move(middle), m2).begin(); |
9367 | | // len12 and len21 now have swapped meanings |
9368 | | // merge smaller range with recursive call and larger with tail |
9369 | | // recursion elimination |
9370 | | if (len11 + len21 < len12 + len22) { |
9371 | | impl_slow(std::move(first), std::move(m1), middle, len11, |
9372 | | len21, pred, proj); |
9373 | | first = std::move(middle); |
9374 | | middle = std::move(m2); |
9375 | | len1 = len12; |
9376 | | len2 = len22; |
9377 | | } |
9378 | | else { |
9379 | | impl_slow(middle, std::move(m2), std::move(last), len12, |
9380 | | len22, pred, proj); |
9381 | | last = std::move(middle); |
9382 | | middle = std::move(m1); |
9383 | | len1 = len11; |
9384 | | len2 = len21; |
9385 | | } |
9386 | | } |
9387 | | } |
9388 | | |
9389 | | template <typename I, typename Buf, typename Comp, typename Proj> |
9390 | | static void impl_buffered(I first, |
9391 | | I middle, |
9392 | | I last, |
9393 | | iter_difference_t<I> len1, |
9394 | | iter_difference_t<I> len2, |
9395 | | Buf& buf, |
9396 | | Comp& comp, |
9397 | | Proj& proj) |
9398 | | { |
9399 | | if (len1 <= len2) { |
9400 | | nano::move(first, middle, nano::back_inserter(buf)); |
9401 | | nano::merge(nano::make_move_iterator(buf.begin()), |
9402 | | nano::make_move_sentinel(buf.end()), |
9403 | | nano::make_move_iterator(std::move(middle)), |
9404 | | nano::make_move_sentinel(std::move(last)), |
9405 | | std::move(first), std::ref(comp), std::ref(proj), |
9406 | | std::ref(proj)); |
9407 | | } |
9408 | | else { |
9409 | | nano::move(middle, last, nano::back_inserter(buf)); |
9410 | | using ri_t = nano::reverse_iterator<I>; |
9411 | | // TODO: C++17's not_fn would be useful |
9412 | | auto not_comp = [&comp](auto&& a, auto&& b) { |
9413 | | return !nano::invoke(comp, std::forward<decltype(a)>(a), |
9414 | | std::forward<decltype(b)>(b)); |
9415 | | }; |
9416 | | nano::merge(nano::make_move_iterator(ri_t{std::move(middle)}), |
9417 | | nano::make_move_sentinel(ri_t{std::move(first)}), |
9418 | | nano::make_move_iterator(nano::rbegin(buf)), |
9419 | | nano::make_move_sentinel(nano::rend(buf)), |
9420 | | nano::make_reverse_iterator(std::move(last)), |
9421 | | not_comp, std::ref(proj), std::ref(proj)); |
9422 | | } |
9423 | | } |
9424 | | |
9425 | | template <typename I, typename S, typename Comp, typename Proj> |
9426 | | static I impl(I first, I middle, S last, Comp& comp, Proj& proj) |
9427 | | { |
9428 | | auto dist1 = nano::distance(first, middle); |
9429 | | I ilast = middle; |
9430 | | iter_difference_t<I> dist2 = 0; |
9431 | | while (ilast != last) { |
9432 | | ++ilast; |
9433 | | ++dist2; |
9434 | | } |
9435 | | |
9436 | | const auto sz = nano::min(dist1, dist2); |
9437 | | auto buf = detail::temporary_vector<iter_value_t<I>>(sz); |
9438 | | |
9439 | | if (buf.capacity() >= static_cast<std::size_t>(sz)) { |
9440 | | impl_buffered(std::move(first), std::move(middle), |
9441 | | std::move(ilast), dist1, dist2, buf, comp, proj); |
9442 | | } |
9443 | | else { |
9444 | | impl_slow(std::move(first), std::move(middle), std::move(ilast), |
9445 | | dist1, dist2, comp, proj); |
9446 | | } |
9447 | | |
9448 | | return ilast; |
9449 | | } |
9450 | | |
9451 | | public: |
9452 | | template <typename I, |
9453 | | typename S, |
9454 | | typename Comp = ranges::less, |
9455 | | typename Proj = identity> |
9456 | | std::enable_if_t<bidirectional_iterator<I> && sentinel_for<S, I> && |
9457 | | sortable<I, Comp, Proj>, |
9458 | | I> |
9459 | | operator()(I first, |
9460 | | I middle, |
9461 | | S last, |
9462 | | Comp comp = Comp{}, |
9463 | | Proj proj = Proj{}) const |
9464 | | { |
9465 | | return inplace_merge_fn::impl(std::move(first), std::move(middle), |
9466 | | std::move(last), comp, proj); |
9467 | | } |
9468 | | |
9469 | | template <typename Rng, |
9470 | | typename Comp = ranges::less, |
9471 | | typename Proj = identity> |
9472 | | std::enable_if_t<bidirectional_range<Rng> && |
9473 | | sortable<iterator_t<Rng>, Comp, Proj>, |
9474 | | borrowed_iterator_t<Rng>> |
9475 | | operator()(Rng&& rng, |
9476 | | iterator_t<Rng> middle, |
9477 | | Comp comp = Comp{}, |
9478 | | Proj proj = Proj{}) const |
9479 | | { |
9480 | | return inplace_merge_fn::impl(nano::begin(rng), std::move(middle), |
9481 | | nano::end(rng), comp, proj); |
9482 | | } |
9483 | | }; |
9484 | | |
9485 | | } // namespace detail |
9486 | | |
9487 | | NANO_INLINE_VAR(detail::inplace_merge_fn, inplace_merge) |
9488 | | |
9489 | | NANO_END_NAMESPACE |
9490 | | |
9491 | | #endif |
9492 | | |
9493 | | // nanorange/algorithm/is_heap.hpp |
9494 | | // |
9495 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
9496 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9497 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9498 | | |
9499 | | #ifndef NANORANGE_ALGORITHM_IS_HEAP_HPP_INCLUDED |
9500 | | #define NANORANGE_ALGORITHM_IS_HEAP_HPP_INCLUDED |
9501 | | |
9502 | | // nanorange/algorithm/is_heap_until.hpp |
9503 | | // |
9504 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
9505 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9506 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9507 | | |
9508 | | // Uses code from CMCSTL2 |
9509 | | // |
9510 | | // Copyright Eric Niebler 2014 |
9511 | | // Copyright Casey Carter 2015 |
9512 | | |
9513 | | #ifndef NANORANGE_ALGORITHM_IS_HEAP_UNTIL_HPP_INCLUDED |
9514 | | #define NANORANGE_ALGORITHM_IS_HEAP_UNTIL_HPP_INCLUDED |
9515 | | |
9516 | | NANO_BEGIN_NAMESPACE |
9517 | | |
9518 | | namespace detail { |
9519 | | |
9520 | | struct is_heap_until_fn { |
9521 | | private: |
9522 | | friend struct is_heap_fn; |
9523 | | |
9524 | | template <typename I, typename Comp, typename Proj> |
9525 | | static constexpr I impl(I first, |
9526 | | const iter_difference_t<I> n, |
9527 | | Comp& comp, |
9528 | | Proj& proj) |
9529 | | { |
9530 | | iter_difference_t<I> p = 0, c = 1; |
9531 | | |
9532 | | I pp = first; |
9533 | | |
9534 | | while (c < n) { |
9535 | | I cp = first + c; |
9536 | | |
9537 | | if (nano::invoke(comp, nano::invoke(proj, *pp), |
9538 | | nano::invoke(proj, *cp))) { |
9539 | | return cp; |
9540 | | } |
9541 | | |
9542 | | ++c; |
9543 | | ++cp; |
9544 | | |
9545 | | if (c == n || nano::invoke(comp, nano::invoke(proj, *pp), |
9546 | | nano::invoke(proj, *cp))) { |
9547 | | return cp; |
9548 | | } |
9549 | | |
9550 | | ++p; |
9551 | | ++pp; |
9552 | | |
9553 | | c = 2 * p + 1; |
9554 | | } |
9555 | | |
9556 | | return first + n; |
9557 | | } |
9558 | | |
9559 | | public: |
9560 | | template <typename I, |
9561 | | typename S, |
9562 | | typename Comp = ranges::less, |
9563 | | typename Proj = identity> |
9564 | | constexpr std::enable_if_t< |
9565 | | random_access_iterator<I> && sentinel_for<S, I> && |
9566 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
9567 | | I> |
9568 | | operator()(I first, |
9569 | | S last, |
9570 | | Comp comp = Comp{}, |
9571 | | Proj proj = Proj{}) const |
9572 | | { |
9573 | | auto n = nano::distance(first, last); |
9574 | | return is_heap_until_fn::impl(std::move(first), n, comp, proj); |
9575 | | } |
9576 | | |
9577 | | template <typename Rng, |
9578 | | typename Comp = ranges::less, |
9579 | | typename Proj = identity> |
9580 | | constexpr std::enable_if_t< |
9581 | | random_access_range<Rng> && |
9582 | | indirect_strict_weak_order<Comp, |
9583 | | projected<iterator_t<Rng>, Proj>>, |
9584 | | borrowed_iterator_t<Rng>> |
9585 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
9586 | | { |
9587 | | return is_heap_until_fn::impl(nano::begin(rng), nano::distance(rng), |
9588 | | comp, proj); |
9589 | | } |
9590 | | }; |
9591 | | |
9592 | | } // namespace detail |
9593 | | |
9594 | | NANO_INLINE_VAR(detail::is_heap_until_fn, is_heap_until) |
9595 | | |
9596 | | NANO_END_NAMESPACE |
9597 | | |
9598 | | #endif |
9599 | | |
9600 | | NANO_BEGIN_NAMESPACE |
9601 | | |
9602 | | namespace detail { |
9603 | | |
9604 | | struct is_heap_fn { |
9605 | | template <typename I, |
9606 | | typename S, |
9607 | | typename Comp = ranges::less, |
9608 | | typename Proj = identity> |
9609 | | std::enable_if_t< |
9610 | | random_access_iterator<I> && sentinel_for<S, I> && |
9611 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
9612 | | bool> |
9613 | | operator()(I first, |
9614 | | S last, |
9615 | | Comp comp = Comp{}, |
9616 | | Proj proj = Proj{}) const |
9617 | | { |
9618 | | const auto n = nano::distance(first, last); |
9619 | | return is_heap_until_fn::impl(std::move(first), n, comp, proj) == |
9620 | | last; |
9621 | | } |
9622 | | |
9623 | | template <typename Rng, |
9624 | | typename Comp = ranges::less, |
9625 | | typename Proj = identity> |
9626 | | std::enable_if_t< |
9627 | | random_access_range<Rng> && |
9628 | | indirect_strict_weak_order<Comp, |
9629 | | projected<iterator_t<Rng>, Proj>>, |
9630 | | bool> |
9631 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
9632 | | { |
9633 | | return is_heap_until_fn::impl(nano::begin(rng), nano::distance(rng), |
9634 | | comp, proj) == nano::end(rng); |
9635 | | } |
9636 | | }; |
9637 | | |
9638 | | } // namespace detail |
9639 | | |
9640 | | NANO_INLINE_VAR(detail::is_heap_fn, is_heap) |
9641 | | |
9642 | | NANO_END_NAMESPACE |
9643 | | |
9644 | | #endif |
9645 | | |
9646 | | // nanorange/algorithm/is_partitioned.hpp |
9647 | | // |
9648 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
9649 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9650 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9651 | | |
9652 | | #ifndef NANORANGE_ALGORITHM_IS_PARTITIONED_HPP_INCLUDED |
9653 | | #define NANORANGE_ALGORITHM_IS_PARTITIONED_HPP_INCLUDED |
9654 | | |
9655 | | NANO_BEGIN_NAMESPACE |
9656 | | |
9657 | | namespace detail { |
9658 | | |
9659 | | struct is_partitioned_fn { |
9660 | | private: |
9661 | | template <typename I, typename S, typename Pred, typename Proj> |
9662 | | static constexpr bool impl(I first, S last, Pred& pred, Proj& proj) |
9663 | | { |
9664 | | first = nano::find_if_not(std::move(first), last, pred, proj); |
9665 | | return nano::find_if(std::move(first), last, pred, proj) == last; |
9666 | | } |
9667 | | |
9668 | | public: |
9669 | | template <typename I, |
9670 | | typename S, |
9671 | | typename Pred, |
9672 | | typename Proj = identity> |
9673 | | constexpr std::enable_if_t< |
9674 | | input_iterator<I> && sentinel_for<S, I> && |
9675 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
9676 | | bool> |
9677 | | operator()(I first, |
9678 | | S last, |
9679 | | Pred pred = Pred{}, |
9680 | | Proj proj = Proj{}) const |
9681 | | { |
9682 | | return is_partitioned_fn::impl(std::move(first), std::move(last), |
9683 | | pred, proj); |
9684 | | } |
9685 | | |
9686 | | template <typename Rng, typename Pred, typename Proj = identity> |
9687 | | constexpr std::enable_if_t< |
9688 | | input_range<Rng> && |
9689 | | indirect_unary_predicate<Pred, |
9690 | | projected<iterator_t<Rng>, Proj>>, |
9691 | | bool> |
9692 | | operator()(Rng&& rng, Pred pred = Pred{}, Proj proj = Proj{}) const |
9693 | | { |
9694 | | return is_partitioned_fn::impl(nano::begin(rng), nano::end(rng), |
9695 | | pred, proj); |
9696 | | } |
9697 | | }; |
9698 | | |
9699 | | } // namespace detail |
9700 | | |
9701 | | NANO_INLINE_VAR(detail::is_partitioned_fn, is_partitioned) |
9702 | | |
9703 | | NANO_END_NAMESPACE |
9704 | | |
9705 | | #endif |
9706 | | |
9707 | | // nanorange/algorithm/is_permutation.hpp |
9708 | | // |
9709 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
9710 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9711 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9712 | | |
9713 | | #ifndef NANORANGE_ALGORITHM_IS_PERMUTATION_HPP_INCLUDED |
9714 | | #define NANORANGE_ALGORITHM_IS_PERMUTATION_HPP_INCLUDED |
9715 | | |
9716 | | // nanorange/algorithm/mismatch.hpp |
9717 | | // |
9718 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
9719 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9720 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9721 | | |
9722 | | #ifndef NANORANGE_ALGORITHM_MISMATCH_HPP_INCLUDED |
9723 | | #define NANORANGE_ALGORITHM_MISMATCH_HPP_INCLUDED |
9724 | | |
9725 | | NANO_BEGIN_NAMESPACE |
9726 | | |
9727 | | // [range.mismatch] |
9728 | | |
9729 | | template <typename I1, typename I2> |
9730 | | using mismatch_result = in_in_result<I1, I2>; |
9731 | | |
9732 | | namespace detail { |
9733 | | |
9734 | | struct mismatch_fn { |
9735 | | private: |
9736 | | friend struct is_permutation_fn; |
9737 | | |
9738 | | template <typename I1, |
9739 | | typename S1, |
9740 | | typename I2, |
9741 | | typename Proj1, |
9742 | | typename Proj2, |
9743 | | typename Pred> |
9744 | | static constexpr mismatch_result<I1, I2> impl3(I1 first1, |
9745 | | S1 last1, |
9746 | | I2 first2, |
9747 | | Pred& pred, |
9748 | | Proj1& proj1, |
9749 | | Proj2& proj2) |
9750 | | { |
9751 | | while (first1 != last1 && |
9752 | | nano::invoke(pred, nano::invoke(proj1, *first1), |
9753 | | nano::invoke(proj2, *first2))) { |
9754 | | ++first1; |
9755 | | ++first2; |
9756 | | } |
9757 | | |
9758 | | return {first1, first2}; |
9759 | | } |
9760 | | |
9761 | | template <typename I1, |
9762 | | typename S1, |
9763 | | typename I2, |
9764 | | typename S2, |
9765 | | typename Proj1, |
9766 | | typename Proj2, |
9767 | | typename Pred> |
9768 | | static constexpr mismatch_result<I1, I2> impl4(I1 first1, |
9769 | | S1 last1, |
9770 | | I2 first2, |
9771 | | S2 last2, |
9772 | | Pred& pred, |
9773 | | Proj1& proj1, |
9774 | | Proj2& proj2) |
9775 | | { |
9776 | | while (first1 != last1 && first2 != last2 && |
9777 | | nano::invoke(pred, nano::invoke(proj1, *first1), |
9778 | | nano::invoke(proj2, *first2))) { |
9779 | | ++first1; |
9780 | | ++first2; |
9781 | | } |
9782 | | |
9783 | | return {first1, first2}; |
9784 | | } |
9785 | | |
9786 | | public: |
9787 | | // three legged |
9788 | | template <typename I1, |
9789 | | typename S1, |
9790 | | typename I2, |
9791 | | typename Proj1 = identity, |
9792 | | typename Proj2 = identity, |
9793 | | typename Pred = ranges::equal_to> |
9794 | | NANO_DEPRECATED constexpr std::enable_if_t< |
9795 | | input_iterator<I1> && sentinel_for<S1, I1> && |
9796 | | input_iterator<std::decay_t<I2>> && !input_range<I1> && |
9797 | | indirect_relation<Pred, |
9798 | | projected<I1, Proj1>, |
9799 | | projected<std::decay_t<I2>, Proj2>>, |
9800 | | mismatch_result<I1, std::decay_t<I2>>> |
9801 | | operator()(I1 first1, |
9802 | | S1 last1, |
9803 | | I2&& first2, |
9804 | | Pred pred = Pred{}, |
9805 | | Proj1 proj1 = Proj1{}, |
9806 | | Proj2 proj2 = Proj2{}) const |
9807 | | { |
9808 | | return mismatch_fn::impl3(std::move(first1), std::move(last1), |
9809 | | std::forward<I2>(first2), pred, proj1, |
9810 | | proj2); |
9811 | | } |
9812 | | |
9813 | | // range and a half |
9814 | | template <typename Rng1, |
9815 | | typename I2, |
9816 | | typename Proj1 = identity, |
9817 | | typename Proj2 = identity, |
9818 | | typename Pred = ranges::equal_to> |
9819 | | NANO_DEPRECATED constexpr std::enable_if_t< |
9820 | | input_range<Rng1> && input_iterator<std::decay_t<I2>> && |
9821 | | !input_range<I2> && |
9822 | | indirect_relation<Pred, |
9823 | | projected<iterator_t<Rng1>, Proj1>, |
9824 | | projected<std::decay_t<I2>, Proj2>>, |
9825 | | mismatch_result<borrowed_iterator_t<Rng1>, std::decay_t<I2>>> |
9826 | | operator()(Rng1&& rng1, |
9827 | | I2&& first2, |
9828 | | Pred pred = Pred{}, |
9829 | | Proj1 proj1 = Proj1{}, |
9830 | | Proj2 proj2 = Proj2{}) const |
9831 | | { |
9832 | | return mismatch_fn::impl3(nano::begin(rng1), nano::end(rng1), |
9833 | | std::forward<I2>(first2), pred, proj1, |
9834 | | proj2); |
9835 | | } |
9836 | | |
9837 | | // four legged |
9838 | | template <typename I1, |
9839 | | typename S1, |
9840 | | typename I2, |
9841 | | typename S2, |
9842 | | typename Proj1 = identity, |
9843 | | typename Proj2 = identity, |
9844 | | typename Pred = ranges::equal_to> |
9845 | | constexpr std::enable_if_t<input_iterator<I1> && sentinel_for<S1, I1> && |
9846 | | input_iterator<I2> && |
9847 | | sentinel_for<S2, I2> && |
9848 | | indirect_relation<Pred, |
9849 | | projected<I1, Proj1>, |
9850 | | projected<I2, Proj2>>, |
9851 | | mismatch_result<I1, I2>> |
9852 | | operator()(I1 first1, |
9853 | | S1 last1, |
9854 | | I2 first2, |
9855 | | S2 last2, |
9856 | | Pred pred = Pred{}, |
9857 | | Proj1 proj1 = Proj1{}, |
9858 | | Proj2 proj2 = Proj2{}) const |
9859 | | { |
9860 | | return mismatch_fn::impl4(std::move(first1), std::move(last1), |
9861 | | std::move(first2), std::move(last2), pred, |
9862 | | proj1, proj2); |
9863 | | } |
9864 | | |
9865 | | // two ranges |
9866 | | template <typename Rng1, |
9867 | | typename Rng2, |
9868 | | typename Proj1 = identity, |
9869 | | typename Proj2 = identity, |
9870 | | typename Pred = ranges::equal_to> |
9871 | | constexpr std::enable_if_t< |
9872 | | input_range<Rng1> && input_range<Rng2> && |
9873 | | indirect_relation<Pred, |
9874 | | projected<iterator_t<Rng1>, Proj1>, |
9875 | | projected<iterator_t<Rng2>, Proj2>>, |
9876 | | mismatch_result<borrowed_iterator_t<Rng1>, |
9877 | | borrowed_iterator_t<Rng2>>> |
9878 | | operator()(Rng1&& rng1, |
9879 | | Rng2&& rng2, |
9880 | | Pred pred = Pred{}, |
9881 | | Proj1 proj1 = Proj1{}, |
9882 | | Proj2 proj2 = Proj2{}) const |
9883 | | { |
9884 | | return mismatch_fn::impl4(nano::begin(rng1), nano::end(rng1), |
9885 | | nano::begin(rng2), nano::end(rng2), pred, |
9886 | | proj1, proj2); |
9887 | | } |
9888 | | }; |
9889 | | |
9890 | | } // namespace detail |
9891 | | |
9892 | | NANO_INLINE_VAR(detail::mismatch_fn, mismatch) |
9893 | | |
9894 | | NANO_END_NAMESPACE |
9895 | | |
9896 | | #endif |
9897 | | |
9898 | | NANO_BEGIN_NAMESPACE |
9899 | | |
9900 | | namespace detail { |
9901 | | |
9902 | | struct is_permutation_fn { |
9903 | | private: |
9904 | | template <typename I1, |
9905 | | typename S1, |
9906 | | typename I2, |
9907 | | typename S2, |
9908 | | typename Pred, |
9909 | | typename Proj1, |
9910 | | typename Proj2> |
9911 | | static constexpr bool process_tail(I1 first1, |
9912 | | S1 last1, |
9913 | | I2 first2, |
9914 | | S2 last2, |
9915 | | Pred& pred, |
9916 | | Proj1& proj1, |
9917 | | Proj2& proj2) |
9918 | | { |
9919 | | for (auto it = first1; it != last1; ++it) { |
9920 | | const auto comp = |
9921 | | [&pred, val = nano::invoke(proj1, *it)](const auto& t) { |
9922 | | return nano::invoke(pred, t, val); |
9923 | | }; |
9924 | | |
9925 | | // Check whether we have already seen this value |
9926 | | if (any_of_fn::impl(first1, it, comp, proj1)) { |
9927 | | continue; |
9928 | | } |
9929 | | |
9930 | | // Count how many times *it appears in range2 |
9931 | | const auto count1 = |
9932 | | count_if_fn::impl(first2, last2, comp, proj2); |
9933 | | |
9934 | | // If we have a count of zero, we know the ranges are different |
9935 | | if (count1 == 0) { |
9936 | | return false; |
9937 | | } |
9938 | | |
9939 | | // Count how many times *it appears in the remainder of range1 |
9940 | | // (we can start from one) |
9941 | | const auto count2 = |
9942 | | iter_difference_t<I1>{1} + |
9943 | | count_if_fn::impl(nano::next(it), last1, comp, proj1); |
9944 | | |
9945 | | if (count1 != count2) { |
9946 | | return false; |
9947 | | } |
9948 | | } |
9949 | | |
9950 | | return true; |
9951 | | } |
9952 | | |
9953 | | template <typename I1, |
9954 | | typename S1, |
9955 | | typename I2, |
9956 | | typename Pred, |
9957 | | typename Proj1, |
9958 | | typename Proj2> |
9959 | | static constexpr bool impl3(I1 first1, |
9960 | | S1 last1, |
9961 | | I2 first2, |
9962 | | Pred& pred, |
9963 | | Proj1& proj1, |
9964 | | Proj2& proj2) |
9965 | | { |
9966 | | // Strip equal prefixes from both ranges |
9967 | | auto result = |
9968 | | mismatch_fn::impl3(std::move(first1), last1, std::move(first2), |
9969 | | pred, proj1, proj2); |
9970 | | first1 = std::move(result).in1; |
9971 | | first2 = std::move(result).in2; |
9972 | | |
9973 | | if (first1 == last1) { |
9974 | | return true; |
9975 | | } |
9976 | | |
9977 | | // If we have only one value left in range1, it can't be in range2 |
9978 | | const auto d = nano::distance(first1, last1); |
9979 | | if (d == 1) { |
9980 | | return false; |
9981 | | } |
9982 | | |
9983 | | auto last2 = nano::next(first2, d); |
9984 | | |
9985 | | return is_permutation_fn::process_tail( |
9986 | | std::move(first1), std::move(last1), std::move(first2), |
9987 | | std::move(last2), pred, proj1, proj2); |
9988 | | } |
9989 | | |
9990 | | template <typename I1, |
9991 | | typename S1, |
9992 | | typename I2, |
9993 | | typename S2, |
9994 | | typename Pred, |
9995 | | typename Proj1, |
9996 | | typename Proj2> |
9997 | | static constexpr bool impl4(I1 first1, |
9998 | | S1 last1, |
9999 | | I2 first2, |
10000 | | S2 last2, |
10001 | | Pred& pred, |
10002 | | Proj1& proj1, |
10003 | | Proj2& proj2) |
10004 | | { |
10005 | | // Strip equal prefixes from both ranges |
10006 | | auto result = |
10007 | | mismatch_fn::impl4(std::move(first1), last1, std::move(first2), |
10008 | | last2, pred, proj1, proj2); |
10009 | | first1 = std::move(result).in1; |
10010 | | first2 = std::move(result).in2; |
10011 | | |
10012 | | // If we have reached the end of both ranges, they were the same |
10013 | | if (first1 == last1 && first2 == last2) { |
10014 | | return true; |
10015 | | } |
10016 | | |
10017 | | // If we have different numbers of elements left in the ranges, |
10018 | | // they are not permutations of one another |
10019 | | if (nano::distance(first1, last1) != |
10020 | | nano::distance(first2, last2)) { |
10021 | | return false; |
10022 | | } |
10023 | | |
10024 | | return is_permutation_fn::process_tail( |
10025 | | std::move(first1), std::move(last1), std::move(first2), |
10026 | | std::move(last2), pred, proj1, proj2); |
10027 | | } |
10028 | | |
10029 | | public: |
10030 | | // Four-legged |
10031 | | template <typename I1, |
10032 | | typename S1, |
10033 | | typename I2, |
10034 | | typename S2, |
10035 | | typename Pred = ranges::equal_to, |
10036 | | typename Proj1 = identity, |
10037 | | typename Proj2 = identity> |
10038 | | constexpr std::enable_if_t< |
10039 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
10040 | | forward_iterator<I2> && sentinel_for<S2, I2> && |
10041 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2>, |
10042 | | bool> |
10043 | | operator()(I1 first1, |
10044 | | S1 last1, |
10045 | | I2 first2, |
10046 | | S2 last2, |
10047 | | Pred pred = Pred{}, |
10048 | | Proj1 proj1 = Proj1{}, |
10049 | | Proj2 proj2 = Proj2{}) const |
10050 | | { |
10051 | | if constexpr (sized_sentinel_for<S1, I1> && |
10052 | | sized_sentinel_for<S2, I2>) { |
10053 | | if (nano::distance(first1, last1) != |
10054 | | nano::distance(first2, last2)) { |
10055 | | return false; |
10056 | | } |
10057 | | return is_permutation_fn::impl3( |
10058 | | std::move(first1), std::move(last1), std::move(first2), |
10059 | | pred, proj1, proj2); |
10060 | | } |
10061 | | |
10062 | | return is_permutation_fn::impl4(std::move(first1), std::move(last1), |
10063 | | std::move(first2), std::move(last2), |
10064 | | pred, proj1, proj2); |
10065 | | } |
10066 | | |
10067 | | // Three-legged |
10068 | | template <typename I1, |
10069 | | typename S1, |
10070 | | typename I2, |
10071 | | typename Pred = ranges::equal_to, |
10072 | | typename Proj1 = identity, |
10073 | | typename Proj2 = identity> |
10074 | | NANO_DEPRECATED constexpr std::enable_if_t< |
10075 | | forward_iterator<I1> && sentinel_for<S1, I1> && |
10076 | | forward_iterator<I2> && |
10077 | | indirectly_comparable<I1, I2, Pred, Proj1, Proj2>, |
10078 | | bool> |
10079 | | operator()(I1 first1, |
10080 | | S1 last1, |
10081 | | I2 first2, |
10082 | | Pred pred = Pred{}, |
10083 | | Proj1 proj1 = Proj1{}, |
10084 | | Proj2 proj2 = Proj2{}) const |
10085 | | { |
10086 | | return is_permutation_fn::impl3(std::move(first1), std::move(last1), |
10087 | | std::move(first2), pred, proj1, |
10088 | | proj2); |
10089 | | } |
10090 | | |
10091 | | // Two ranges |
10092 | | template <typename Rng1, |
10093 | | typename Rng2, |
10094 | | typename Pred = ranges::equal_to, |
10095 | | typename Proj1 = identity, |
10096 | | typename Proj2 = identity> |
10097 | | constexpr std::enable_if_t<forward_range<Rng1> && forward_range<Rng2> && |
10098 | | indirectly_comparable<iterator_t<Rng1>, |
10099 | | iterator_t<Rng2>, |
10100 | | Pred, |
10101 | | Proj1, |
10102 | | Proj2>, |
10103 | | bool> |
10104 | | operator()(Rng1&& rng1, |
10105 | | Rng2&& rng2, |
10106 | | Pred pred = Pred{}, |
10107 | | Proj1 proj1 = Proj1{}, |
10108 | | Proj2 proj2 = Proj2{}) const |
10109 | | { |
10110 | | if (sized_range<Rng1> && sized_range<Rng2>) { |
10111 | | if (nano::distance(rng1) != nano::distance(rng2)) { |
10112 | | return false; |
10113 | | } |
10114 | | |
10115 | | return is_permutation_fn::impl3( |
10116 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), pred, |
10117 | | proj1, proj2); |
10118 | | } |
10119 | | |
10120 | | return is_permutation_fn::impl4(nano::begin(rng1), nano::end(rng1), |
10121 | | nano::begin(rng2), nano::end(rng2), |
10122 | | pred, proj1, proj2); |
10123 | | } |
10124 | | |
10125 | | // Range and a half |
10126 | | template <typename Rng1, |
10127 | | typename I2, |
10128 | | typename Pred = ranges::equal_to, |
10129 | | typename Proj1 = identity, |
10130 | | typename Proj2 = identity> |
10131 | | NANO_DEPRECATED constexpr std::enable_if_t< |
10132 | | forward_range<Rng1> && forward_iterator<std::decay_t<I2>> && |
10133 | | !range<I2> && |
10134 | | indirectly_comparable<iterator_t<Rng1>, I2, Pred, Proj1, Proj2>, |
10135 | | bool> |
10136 | | operator()(Rng1&& rng1, |
10137 | | I2&& first2, |
10138 | | Pred pred = Pred{}, |
10139 | | Proj1 proj1 = Proj1{}, |
10140 | | Proj2 proj2 = Proj2{}) const |
10141 | | { |
10142 | | return is_permutation_fn::impl3(nano::begin(rng1), nano::end(rng1), |
10143 | | std::forward<I2>(first2), pred, |
10144 | | proj1, proj2); |
10145 | | } |
10146 | | }; |
10147 | | |
10148 | | } // namespace detail |
10149 | | |
10150 | | NANO_INLINE_VAR(detail::is_permutation_fn, is_permutation) |
10151 | | |
10152 | | NANO_END_NAMESPACE |
10153 | | |
10154 | | #endif |
10155 | | |
10156 | | // nanorange/algorithm/is_sorted.hpp |
10157 | | // |
10158 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10159 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10160 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10161 | | |
10162 | | #ifndef NANORANGE_ALGORITHM_IS_SORTED_HPP_INCLUDED |
10163 | | #define NANORANGE_ALGORITHM_IS_SORTED_HPP_INCLUDED |
10164 | | |
10165 | | // nanorange/algorithm/is_sorted_until.hpp |
10166 | | // |
10167 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10168 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10169 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10170 | | |
10171 | | #ifndef NANORANGE_ALGORITHM_IS_SORTED_UNTIL_HPP_INCLUDED |
10172 | | #define NANORANGE_ALGORITHM_IS_SORTED_UNTIL_HPP_INCLUDED |
10173 | | |
10174 | | NANO_BEGIN_NAMESPACE |
10175 | | |
10176 | | namespace detail { |
10177 | | |
10178 | | struct is_sorted_until_fn { |
10179 | | private: |
10180 | | friend struct is_sorted_fn; |
10181 | | |
10182 | | template <typename I, typename S, typename Comp, typename Proj> |
10183 | | static constexpr I impl(I first, S last, Comp& comp, Proj& proj) |
10184 | | { |
10185 | | if (first == last) { |
10186 | | return first; |
10187 | | } |
10188 | | |
10189 | | I n = next(first); |
10190 | | |
10191 | | while (n != last) { |
10192 | | if (nano::invoke(comp, nano::invoke(proj, *n), |
10193 | | nano::invoke(proj, *first))) { |
10194 | | return n; |
10195 | | } |
10196 | | ++first; |
10197 | | ++n; |
10198 | | } |
10199 | | |
10200 | | return n; |
10201 | | } |
10202 | | |
10203 | | public: |
10204 | | template <typename I, |
10205 | | typename S, |
10206 | | typename Comp = ranges::less, |
10207 | | typename Proj = identity> |
10208 | | constexpr std::enable_if_t< |
10209 | | forward_iterator<I> && sentinel_for<S, I> && |
10210 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
10211 | | I> |
10212 | | operator()(I first, |
10213 | | S last, |
10214 | | Comp comp = Comp{}, |
10215 | | Proj proj = Proj{}) const |
10216 | | { |
10217 | | return is_sorted_until_fn::impl(std::move(first), std::move(last), |
10218 | | comp, proj); |
10219 | | } |
10220 | | |
10221 | | template <typename Rng, |
10222 | | typename Comp = ranges::less, |
10223 | | typename Proj = identity> |
10224 | | constexpr std::enable_if_t< |
10225 | | forward_range<Rng> && |
10226 | | indirect_strict_weak_order<Comp, |
10227 | | projected<iterator_t<Rng>, Proj>>, |
10228 | | borrowed_iterator_t<Rng>> |
10229 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10230 | | { |
10231 | | return is_sorted_until_fn::impl(nano::begin(rng), nano::end(rng), |
10232 | | comp, proj); |
10233 | | } |
10234 | | }; |
10235 | | |
10236 | | } // namespace detail |
10237 | | |
10238 | | NANO_INLINE_VAR(detail::is_sorted_until_fn, is_sorted_until) |
10239 | | |
10240 | | NANO_END_NAMESPACE |
10241 | | |
10242 | | #endif |
10243 | | |
10244 | | NANO_BEGIN_NAMESPACE |
10245 | | |
10246 | | namespace detail { |
10247 | | |
10248 | | struct is_sorted_fn { |
10249 | | template <typename I, |
10250 | | typename S, |
10251 | | typename Comp = ranges::less, |
10252 | | typename Proj = identity> |
10253 | | constexpr std::enable_if_t< |
10254 | | forward_iterator<I> && sentinel_for<S, I> && |
10255 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
10256 | | bool> |
10257 | | operator()(I first, |
10258 | | S last, |
10259 | | Comp comp = Comp{}, |
10260 | | Proj proj = Proj{}) const |
10261 | | { |
10262 | | return is_sorted_until_fn::impl(std::move(first), last, comp, |
10263 | | proj) == last; |
10264 | | } |
10265 | | |
10266 | | template <typename Rng, |
10267 | | typename Comp = ranges::less, |
10268 | | typename Proj = identity> |
10269 | | constexpr std::enable_if_t< |
10270 | | forward_range<Rng> && |
10271 | | indirect_strict_weak_order<Comp, |
10272 | | projected<iterator_t<Rng>, Proj>>, |
10273 | | bool> |
10274 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10275 | | { |
10276 | | return is_sorted_until_fn::impl(nano::begin(rng), nano::end(rng), |
10277 | | comp, proj) == nano::end(rng); |
10278 | | } |
10279 | | }; |
10280 | | |
10281 | | } // namespace detail |
10282 | | |
10283 | | NANO_INLINE_VAR(detail::is_sorted_fn, is_sorted) |
10284 | | |
10285 | | NANO_END_NAMESPACE |
10286 | | |
10287 | | #endif |
10288 | | |
10289 | | // nanorange/algorithm/stl/lexicographical_compare.hpp |
10290 | | // |
10291 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10292 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10293 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10294 | | |
10295 | | #ifndef NANORANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED |
10296 | | #define NANORANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED |
10297 | | |
10298 | | NANO_BEGIN_NAMESPACE |
10299 | | |
10300 | | namespace detail { |
10301 | | |
10302 | | struct lexicographical_compare_fn { |
10303 | | private: |
10304 | | template <typename I1, |
10305 | | typename S1, |
10306 | | typename I2, |
10307 | | typename S2, |
10308 | | typename Comp, |
10309 | | typename Proj1, |
10310 | | typename Proj2> |
10311 | | static constexpr bool impl(I1 first1, |
10312 | | S1 last1, |
10313 | | I2 first2, |
10314 | | S2 last2, |
10315 | | Comp& comp, |
10316 | | Proj1& proj1, |
10317 | | Proj2& proj2) |
10318 | | { |
10319 | | while (first1 != last1 && first2 != last2) { |
10320 | | if (nano::invoke(comp, nano::invoke(proj1, *first1), |
10321 | | nano::invoke(proj2, *first2))) { |
10322 | | return true; |
10323 | | } |
10324 | | if (nano::invoke(comp, nano::invoke(proj2, *first2), |
10325 | | nano::invoke(proj1, *first1))) { |
10326 | | return false; |
10327 | | } |
10328 | | ++first1; |
10329 | | ++first2; |
10330 | | } |
10331 | | |
10332 | | return first1 == last1 && first2 != last2; |
10333 | | } |
10334 | | |
10335 | | public: |
10336 | | template <typename I1, |
10337 | | typename S1, |
10338 | | typename I2, |
10339 | | typename S2, |
10340 | | typename Comp = ranges::less, |
10341 | | typename Proj1 = identity, |
10342 | | typename Proj2 = identity> |
10343 | | constexpr std::enable_if_t< |
10344 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
10345 | | sentinel_for<S2, I2> && |
10346 | | indirect_strict_weak_order<Comp, |
10347 | | projected<I1, Proj1>, |
10348 | | projected<I2, Proj2>>, |
10349 | | bool> |
10350 | | operator()(I1 first1, |
10351 | | S1 last1, |
10352 | | I2 first2, |
10353 | | S2 last2, |
10354 | | Comp comp = Comp{}, |
10355 | | Proj1 proj1 = Proj1{}, |
10356 | | Proj2 proj2 = Proj2{}) const |
10357 | | { |
10358 | | return lexicographical_compare_fn::impl( |
10359 | | std::move(first1), std::move(last1), std::move(first2), |
10360 | | std::move(last2), comp, proj1, proj2); |
10361 | | } |
10362 | | |
10363 | | template <typename Rng1, |
10364 | | typename Rng2, |
10365 | | typename Comp = ranges::less, |
10366 | | typename Proj1 = identity, |
10367 | | typename Proj2 = identity> |
10368 | | constexpr std::enable_if_t< |
10369 | | input_range<Rng1> && input_range<Rng2> && |
10370 | | indirect_strict_weak_order<Comp, |
10371 | | projected<iterator_t<Rng1>, Proj1>, |
10372 | | projected<iterator_t<Rng2>, Proj2>>, |
10373 | | bool> |
10374 | | operator()(Rng1&& rng1, |
10375 | | Rng2&& rng2, |
10376 | | Comp comp = Comp{}, |
10377 | | Proj1 proj1 = Proj1{}, |
10378 | | Proj2 proj2 = Proj2{}) const |
10379 | | { |
10380 | | return lexicographical_compare_fn::impl( |
10381 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), |
10382 | | nano::end(rng2), comp, proj1, proj2); |
10383 | | } |
10384 | | }; |
10385 | | |
10386 | | } // namespace detail |
10387 | | |
10388 | | NANO_INLINE_VAR(detail::lexicographical_compare_fn, lexicographical_compare) |
10389 | | |
10390 | | NANO_END_NAMESPACE |
10391 | | |
10392 | | #endif |
10393 | | |
10394 | | // nanorange/algorithm/make_heap.hpp |
10395 | | // |
10396 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10397 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10398 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10399 | | |
10400 | | // Uses code from CMCSTL2 |
10401 | | // Copyright Eric Niebler 2014 |
10402 | | // Copyright Casey Carter 2015 |
10403 | | |
10404 | | #ifndef NANORANGE_ALGORITHM_MAKE_HEAP_HPP_INCLUDED |
10405 | | #define NANORANGE_ALGORITHM_MAKE_HEAP_HPP_INCLUDED |
10406 | | |
10407 | | // nanorange/detail/algorithm/heap_sift.hpp |
10408 | | // |
10409 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10410 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10411 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10412 | | |
10413 | | // cmcstl2 - A concept-enabled C++ standard library |
10414 | | // |
10415 | | // Copyright Eric Niebler 2014 |
10416 | | // Copyright Casey Carter 2015 |
10417 | | // |
10418 | | // Use, modification and distribution is subject to the |
10419 | | // Boost Software License, Version 1.0. (See accompanying |
10420 | | // file LICENSE_1_0.txt or copy at |
10421 | | // http://www.boost.org/LICENSE_1_0.txt) |
10422 | | // |
10423 | | // Project home: https://github.com/caseycarter/cmcstl2 |
10424 | | // |
10425 | | //===----------------------------------------------------------------------===// |
10426 | | // |
10427 | | // The LLVM Compiler Infrastructure |
10428 | | // |
10429 | | // This file is dual licensed under the MIT and the University of Illinois Open |
10430 | | // Source Licenses. See LICENSE.TXT for details. |
10431 | | // |
10432 | | //===----------------------------------------------------------------------===// |
10433 | | // |
10434 | | #ifndef NANORANGE_DETAIL_ALGORITHM_HEAP_SIFT_HPP |
10435 | | #define NANORANGE_DETAIL_ALGORITHM_HEAP_SIFT_HPP |
10436 | | |
10437 | | /////////////////////////////////////////////////////////////////////////// |
10438 | | // detail::sift_up_n and detail::sift_down_n |
10439 | | // (heap implementation details) |
10440 | | // |
10441 | | |
10442 | | NANO_BEGIN_NAMESPACE |
10443 | | |
10444 | | namespace detail { |
10445 | | |
10446 | | template <typename I, typename Comp, typename Proj> |
10447 | | constexpr void sift_up_n(I first, |
10448 | | iter_difference_t<I> n, |
10449 | | Comp& comp, |
10450 | | Proj& proj) |
10451 | | { |
10452 | | if (n > 1) { |
10453 | | I last = first + n; |
10454 | | n = (n - 2) / 2; |
10455 | | I i = first + n; |
10456 | | if (nano::invoke(comp, nano::invoke(proj, *i), |
10457 | | nano::invoke(proj, *--last))) { |
10458 | | iter_value_t<I> v = nano::iter_move(last); |
10459 | | do { |
10460 | | *last = nano::iter_move(i); |
10461 | | last = i; |
10462 | | if (n == 0) { |
10463 | | break; |
10464 | | } |
10465 | | n = (n - 1) / 2; |
10466 | | i = first + n; |
10467 | | } while (nano::invoke(comp, nano::invoke(proj, *i), |
10468 | | nano::invoke(proj, v))); |
10469 | | *last = std::move(v); |
10470 | | } |
10471 | | } |
10472 | | } |
10473 | | |
10474 | | template <typename I, typename Comp, typename Proj> |
10475 | | constexpr void sift_down_n(I first, |
10476 | | iter_difference_t<I> n, |
10477 | | I start, |
10478 | | Comp& comp, |
10479 | | Proj& proj) |
10480 | 5.74k | { |
10481 | | // left-child of start is at 2 * start + 1 |
10482 | | // right-child of start is at 2 * start + 2 |
10483 | 5.74k | auto child = start - first; |
10484 | | |
10485 | 5.74k | if (n < 2 || (n - 2) / 2 < child) { |
10486 | 162 | return; |
10487 | 162 | } |
10488 | | |
10489 | 5.58k | child = 2 * child + 1; |
10490 | 5.58k | I child_i = first + child; |
10491 | | |
10492 | 5.58k | if ((child + 1) < n && |
10493 | 5.58k | nano::invoke(comp, nano::invoke(proj, *child_i), |
10494 | 5.32k | nano::invoke(proj, *(child_i + 1)))) { |
10495 | | // right-child exists and is greater than left-child |
10496 | 654 | ++child_i; |
10497 | 654 | ++child; |
10498 | 654 | } |
10499 | | |
10500 | | // check if we are in heap-order |
10501 | 5.58k | if (nano::invoke(comp, nano::invoke(proj, *child_i), |
10502 | 5.58k | nano::invoke(proj, *start))) { |
10503 | | // we are, start is larger than its largest child |
10504 | 18 | return; |
10505 | 18 | } |
10506 | | |
10507 | 5.56k | iter_value_t<I> top = nano::iter_move(start); |
10508 | 14.3k | do { |
10509 | | // we are not in heap-order, swap the parent with it's largest child |
10510 | 14.3k | *start = nano::iter_move(child_i); |
10511 | 14.3k | start = child_i; |
10512 | | |
10513 | 14.3k | if ((n - 2) / 2 < child) { |
10514 | 5.52k | break; |
10515 | 5.52k | } |
10516 | | |
10517 | | // recompute the child based off of the updated parent |
10518 | 8.82k | child = 2 * child + 1; |
10519 | 8.82k | child_i = first + child; |
10520 | | |
10521 | 8.82k | if ((child + 1) < n && |
10522 | 8.82k | nano::invoke(comp, nano::invoke(proj, *child_i), |
10523 | 8.07k | nano::invoke(proj, *(child_i + 1)))) { |
10524 | | // right-child exists and is greater than left-child |
10525 | 312 | ++child_i; |
10526 | 312 | ++child; |
10527 | 312 | } |
10528 | | |
10529 | | // check if we are in heap-order |
10530 | 8.82k | } while (!nano::invoke(comp, nano::invoke(proj, *child_i), |
10531 | 8.82k | nano::invoke(proj, top))); |
10532 | 0 | *start = std::move(top); |
10533 | 5.56k | } |
10534 | | |
10535 | | } // namespace detail |
10536 | | |
10537 | | NANO_END_NAMESPACE |
10538 | | |
10539 | | #endif |
10540 | | |
10541 | | NANO_BEGIN_NAMESPACE |
10542 | | |
10543 | | namespace detail { |
10544 | | |
10545 | | struct make_heap_fn { |
10546 | | private: |
10547 | | template <typename I, typename Comp, typename Proj> |
10548 | | static constexpr I impl(I first, |
10549 | | iter_difference_t<I> n, |
10550 | | Comp& comp, |
10551 | | Proj& proj) |
10552 | 162 | { |
10553 | 162 | if (n > 1) { |
10554 | | // start from the first parent, there is no need to consider |
10555 | | // children |
10556 | 2.10k | for (auto start = (n - 2) / 2; start >= 0; --start) { |
10557 | 1.94k | detail::sift_down_n(first, n, first + start, comp, proj); |
10558 | 1.94k | } |
10559 | 162 | } |
10560 | | |
10561 | 162 | return first + n; |
10562 | 162 | } |
10563 | | |
10564 | | public: |
10565 | | template <typename I, |
10566 | | typename S, |
10567 | | typename Comp = ranges::less, |
10568 | | typename Proj = identity> |
10569 | | constexpr std::enable_if_t<random_access_iterator<I> && |
10570 | | sentinel_for<S, I> && |
10571 | | sortable<I, Comp, Proj>, |
10572 | | I> |
10573 | | operator()(I first, |
10574 | | S last, |
10575 | | Comp comp = Comp{}, |
10576 | | Proj proj = Proj{}) const |
10577 | 162 | { |
10578 | 162 | const auto n = nano::distance(first, last); |
10579 | 162 | return make_heap_fn::impl(std::move(first), n, comp, proj); |
10580 | 162 | } |
10581 | | |
10582 | | template <typename Rng, |
10583 | | typename Comp = ranges::less, |
10584 | | typename Proj = identity> |
10585 | | constexpr std::enable_if_t<random_access_range<Rng> && |
10586 | | sortable<iterator_t<Rng>, Comp>, |
10587 | | borrowed_iterator_t<Rng>> |
10588 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10589 | | { |
10590 | | return make_heap_fn::impl(nano::begin(rng), nano::distance(rng), |
10591 | | comp, proj); |
10592 | | } |
10593 | | }; |
10594 | | |
10595 | | } // namespace detail |
10596 | | |
10597 | | NANO_INLINE_VAR(detail::make_heap_fn, make_heap) |
10598 | | |
10599 | | NANO_END_NAMESPACE |
10600 | | |
10601 | | #endif |
10602 | | |
10603 | | // nanorange/algorithm/max.hpp |
10604 | | // |
10605 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10606 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10607 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10608 | | |
10609 | | #ifndef NANORANGE_ALGORITHM_MAX_HPP_INCLUDED |
10610 | | #define NANORANGE_ALGORITHM_MAX_HPP_INCLUDED |
10611 | | |
10612 | | NANO_BEGIN_NAMESPACE |
10613 | | |
10614 | | namespace detail { |
10615 | | |
10616 | | struct max_fn { |
10617 | | private: |
10618 | | template <typename Rng, typename Comp, typename Proj> |
10619 | | static constexpr iter_value_t<iterator_t<Rng>> impl(Rng&& rng, |
10620 | | Comp& comp, |
10621 | | Proj& proj) |
10622 | | { |
10623 | | auto first = nano::begin(rng); |
10624 | | const auto last = nano::end(rng); |
10625 | | |
10626 | | // Empty ranges not allowed |
10627 | | auto result = *first; |
10628 | | |
10629 | | while (++first != last) { |
10630 | | auto&& val = *first; |
10631 | | if (nano::invoke(comp, nano::invoke(proj, result), |
10632 | | nano::invoke(proj, val))) { |
10633 | | result = std::forward<decltype(val)>(val); |
10634 | | } |
10635 | | } |
10636 | | |
10637 | | return result; |
10638 | | } |
10639 | | |
10640 | | public: |
10641 | | template <typename T, |
10642 | | typename Comp = ranges::less, |
10643 | | typename Proj = identity> |
10644 | | constexpr std::enable_if_t< |
10645 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
10646 | | const T&> |
10647 | | operator()(const T& a, |
10648 | | const T& b, |
10649 | | Comp comp = Comp{}, |
10650 | | Proj proj = Proj{}) const |
10651 | | { |
10652 | | // *sigh*, this should be fixed in STL2 |
10653 | | return !nano::invoke(comp, nano::invoke(proj, a), |
10654 | | nano::invoke(proj, b)) |
10655 | | ? a |
10656 | | : b; |
10657 | | } |
10658 | | |
10659 | | template <typename T, |
10660 | | typename Comp = ranges::less, |
10661 | | typename Proj = identity> |
10662 | | constexpr std::enable_if_t< |
10663 | | copyable<T> && |
10664 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
10665 | | T> |
10666 | | operator()(std::initializer_list<T> rng, |
10667 | | Comp comp = Comp{}, |
10668 | | Proj proj = Proj{}) const |
10669 | | { |
10670 | | return max_fn::impl(rng, comp, proj); |
10671 | | } |
10672 | | |
10673 | | template <typename Rng, |
10674 | | typename Comp = ranges::less, |
10675 | | typename Proj = identity> |
10676 | | constexpr std::enable_if_t< |
10677 | | input_range<Rng> && copyable<iter_value_t<iterator_t<Rng>>> && |
10678 | | indirect_strict_weak_order<Comp, |
10679 | | projected<iterator_t<Rng>, Proj>>, |
10680 | | range_value_t<Rng>> |
10681 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10682 | | { |
10683 | | return max_fn::impl(std::forward<Rng>(rng), comp, proj); |
10684 | | } |
10685 | | }; |
10686 | | |
10687 | | } // namespace detail |
10688 | | |
10689 | | NANO_INLINE_VAR(detail::max_fn, max) |
10690 | | |
10691 | | NANO_END_NAMESPACE |
10692 | | |
10693 | | #endif |
10694 | | |
10695 | | // nanorange/algorithm/max_element.hpp |
10696 | | // |
10697 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10698 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10699 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10700 | | |
10701 | | #ifndef NANORANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED |
10702 | | #define NANORANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED |
10703 | | |
10704 | | NANO_BEGIN_NAMESPACE |
10705 | | |
10706 | | namespace detail { |
10707 | | |
10708 | | struct max_element_fn { |
10709 | | template <typename I, typename S, typename Comp, typename Proj> |
10710 | | static constexpr I impl(I first, S last, Comp& comp, Proj& proj) |
10711 | | { |
10712 | | if (first == last) { |
10713 | | return first; |
10714 | | } |
10715 | | |
10716 | | I i = nano::next(first); |
10717 | | while (i != last) { |
10718 | | if (!nano::invoke(comp, nano::invoke(proj, *i), |
10719 | | nano::invoke(proj, *first))) { |
10720 | | first = i; |
10721 | | } |
10722 | | ++i; |
10723 | | } |
10724 | | |
10725 | | return first; |
10726 | | } |
10727 | | |
10728 | | public: |
10729 | | template <typename I, |
10730 | | typename S, |
10731 | | typename Comp = ranges::less, |
10732 | | typename Proj = identity> |
10733 | | constexpr std::enable_if_t< |
10734 | | forward_iterator<I> && sentinel_for<S, I> && |
10735 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
10736 | | I> |
10737 | | operator()(I first, |
10738 | | S last, |
10739 | | Comp comp = Comp{}, |
10740 | | Proj proj = Proj{}) const |
10741 | | { |
10742 | | return max_element_fn::impl(std::move(first), std::move(last), comp, |
10743 | | proj); |
10744 | | } |
10745 | | |
10746 | | template <typename Rng, |
10747 | | typename Comp = ranges::less, |
10748 | | typename Proj = identity> |
10749 | | constexpr std::enable_if_t< |
10750 | | forward_range<Rng> && |
10751 | | indirect_strict_weak_order<Comp, |
10752 | | projected<iterator_t<Rng>, Proj>>, |
10753 | | borrowed_iterator_t<Rng>> |
10754 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10755 | | { |
10756 | | return max_element_fn::impl(nano::begin(rng), nano::end(rng), comp, |
10757 | | proj); |
10758 | | } |
10759 | | }; |
10760 | | |
10761 | | } // namespace detail |
10762 | | |
10763 | | NANO_INLINE_VAR(detail::max_element_fn, max_element) |
10764 | | |
10765 | | NANO_END_NAMESPACE |
10766 | | |
10767 | | #endif |
10768 | | |
10769 | | // nanorange/algorithm/min_element.hpp |
10770 | | // |
10771 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10772 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10773 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10774 | | |
10775 | | #ifndef NANORANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED |
10776 | | #define NANORANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED |
10777 | | |
10778 | | NANO_BEGIN_NAMESPACE |
10779 | | |
10780 | | namespace detail { |
10781 | | |
10782 | | struct min_element_fn { |
10783 | | private: |
10784 | | friend struct nth_element_fn; |
10785 | | |
10786 | | template <typename I, typename S, typename Comp, typename Proj> |
10787 | | static constexpr I impl(I first, S last, Comp& comp, Proj& proj) |
10788 | | { |
10789 | | if (first == last) { |
10790 | | return first; |
10791 | | } |
10792 | | |
10793 | | I i = nano::next(first); |
10794 | | while (i != last) { |
10795 | | if (nano::invoke(comp, nano::invoke(proj, *i), |
10796 | | nano::invoke(proj, *first))) { |
10797 | | first = i; |
10798 | | } |
10799 | | ++i; |
10800 | | } |
10801 | | |
10802 | | return first; |
10803 | | } |
10804 | | |
10805 | | public: |
10806 | | template <typename I, |
10807 | | typename S, |
10808 | | typename Comp = ranges::less, |
10809 | | typename Proj = identity> |
10810 | | constexpr std::enable_if_t< |
10811 | | forward_iterator<I> && sentinel_for<S, I> && |
10812 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
10813 | | I> |
10814 | | operator()(I first, |
10815 | | S last, |
10816 | | Comp comp = Comp{}, |
10817 | | Proj proj = Proj{}) const |
10818 | | { |
10819 | | return min_element_fn::impl(std::move(first), std::move(last), comp, |
10820 | | proj); |
10821 | | } |
10822 | | |
10823 | | template <typename Rng, |
10824 | | typename Comp = ranges::less, |
10825 | | typename Proj = identity> |
10826 | | constexpr std::enable_if_t< |
10827 | | forward_range<Rng> && |
10828 | | indirect_strict_weak_order<Comp, |
10829 | | projected<iterator_t<Rng>, Proj>>, |
10830 | | borrowed_iterator_t<Rng>> |
10831 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10832 | | { |
10833 | | return min_element_fn::impl(nano::begin(rng), nano::end(rng), comp, |
10834 | | proj); |
10835 | | } |
10836 | | }; |
10837 | | |
10838 | | } // namespace detail |
10839 | | |
10840 | | NANO_INLINE_VAR(detail::min_element_fn, min_element) |
10841 | | |
10842 | | NANO_END_NAMESPACE |
10843 | | |
10844 | | #endif |
10845 | | |
10846 | | // nanorange/algorithm/minmax.hpp |
10847 | | // |
10848 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
10849 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
10850 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10851 | | |
10852 | | // Uses code from CMCSTL2 |
10853 | | // Copyright Casey Carter 2015 |
10854 | | |
10855 | | #ifndef NANORANGE_ALGORITHM_MINMAX_HPP_INCLUDED |
10856 | | #define NANORANGE_ALGORITHM_MINMAX_HPP_INCLUDED |
10857 | | |
10858 | | NANO_BEGIN_NAMESPACE |
10859 | | |
10860 | | template <typename T> |
10861 | | using minmax_result = min_max_result<T>; |
10862 | | |
10863 | | namespace detail { |
10864 | | |
10865 | | struct minmax_fn { |
10866 | | private: |
10867 | | template <typename Rng, |
10868 | | typename Comp, |
10869 | | typename Proj, |
10870 | | typename T = iter_value_t<iterator_t<Rng>>> |
10871 | | static constexpr minmax_result<T> impl(Rng&& rng, |
10872 | | Comp& comp, |
10873 | | Proj& proj) |
10874 | | { |
10875 | | auto first = nano::begin(rng); |
10876 | | const auto last = nano::end(rng); |
10877 | | |
10878 | | // Empty ranges not allowed |
10879 | | auto temp = *first; |
10880 | | minmax_result<T> result{temp, std::move(temp)}; |
10881 | | |
10882 | | if (++first != last) { |
10883 | | { |
10884 | | auto&& val = *first; |
10885 | | if (nano::invoke(comp, nano::invoke(proj, val), |
10886 | | nano::invoke(proj, result.min))) { |
10887 | | result.min = std::forward<decltype(val)>(val); |
10888 | | } |
10889 | | else if (!nano::invoke(comp, nano::invoke(proj, val), |
10890 | | nano::invoke(proj, result.max))) { |
10891 | | result.max = std::forward<decltype(val)>(val); |
10892 | | } |
10893 | | } |
10894 | | |
10895 | | while (++first != last) { |
10896 | | T val1 = *first; |
10897 | | |
10898 | | // Last iteration |
10899 | | if (++first == last) { |
10900 | | if (nano::invoke(comp, nano::invoke(proj, val1), |
10901 | | nano::invoke(proj, result.min))) { |
10902 | | result.min = std::move(val1); |
10903 | | } |
10904 | | else if (!nano::invoke( |
10905 | | comp, nano::invoke(proj, val1), |
10906 | | nano::invoke(proj, result.max))) { |
10907 | | result.max = std::move(val1); |
10908 | | } |
10909 | | break; |
10910 | | } |
10911 | | |
10912 | | auto&& val2 = *first; |
10913 | | if (nano::invoke(comp, nano::invoke(proj, val2), |
10914 | | nano::invoke(proj, val1))) { |
10915 | | if (nano::invoke(comp, nano::invoke(proj, val2), |
10916 | | nano::invoke(proj, result.min))) { |
10917 | | result.min = std::forward<decltype(val2)>(val2); |
10918 | | } |
10919 | | if (!nano::invoke(comp, nano::invoke(proj, val1), |
10920 | | nano::invoke(proj, result.max))) { |
10921 | | result.max = std::move(val1); |
10922 | | } |
10923 | | } |
10924 | | else { |
10925 | | if (nano::invoke(comp, nano::invoke(proj, val1), |
10926 | | nano::invoke(proj, result.min))) { |
10927 | | result.min = std::move(val1); |
10928 | | } |
10929 | | if (!nano::invoke(comp, nano::invoke(proj, val2), |
10930 | | nano::invoke(proj, result.max))) { |
10931 | | result.max = std::forward<decltype(val2)>(val2); |
10932 | | } |
10933 | | } |
10934 | | } |
10935 | | } |
10936 | | |
10937 | | return result; |
10938 | | } |
10939 | | |
10940 | | public: |
10941 | | template <typename T, |
10942 | | typename Comp = ranges::less, |
10943 | | typename Proj = identity> |
10944 | | constexpr std::enable_if_t< |
10945 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
10946 | | minmax_result<const T&>> |
10947 | | operator()(const T& a, |
10948 | | const T& b, |
10949 | | Comp comp = Comp{}, |
10950 | | Proj proj = Proj{}) const |
10951 | | { |
10952 | | if (nano::invoke(comp, nano::invoke(proj, b), |
10953 | | nano::invoke(proj, a))) { |
10954 | | return {b, a}; |
10955 | | } |
10956 | | else { |
10957 | | return {a, b}; |
10958 | | } |
10959 | | } |
10960 | | |
10961 | | template <typename T, |
10962 | | typename Comp = ranges::less, |
10963 | | typename Proj = identity> |
10964 | | constexpr std::enable_if_t< |
10965 | | copyable<T> && |
10966 | | indirect_strict_weak_order<Comp, projected<const T*, Proj>>, |
10967 | | minmax_result<T>> |
10968 | | operator()(std::initializer_list<T> rng, |
10969 | | Comp comp = Comp{}, |
10970 | | Proj proj = Proj{}) const |
10971 | | { |
10972 | | return minmax_fn::impl(rng, comp, proj); |
10973 | | } |
10974 | | |
10975 | | template <typename Rng, |
10976 | | typename Comp = ranges::less, |
10977 | | typename Proj = identity> |
10978 | | constexpr std::enable_if_t< |
10979 | | input_range<Rng> && copyable<iter_value_t<iterator_t<Rng>>> && |
10980 | | indirect_strict_weak_order<Comp, |
10981 | | projected<iterator_t<Rng>, Proj>>, |
10982 | | minmax_result<range_value_t<Rng>>> |
10983 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
10984 | | { |
10985 | | return minmax_fn::impl(std::forward<Rng>(rng), comp, proj); |
10986 | | } |
10987 | | }; |
10988 | | |
10989 | | } // namespace detail |
10990 | | |
10991 | | NANO_INLINE_VAR(detail::minmax_fn, minmax) |
10992 | | |
10993 | | NANO_END_NAMESPACE |
10994 | | |
10995 | | #endif |
10996 | | |
10997 | | // nanorange/algorithm/minmax_element.hpp |
10998 | | // |
10999 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11000 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11001 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11002 | | |
11003 | | // Uses code from CMCSTL2 |
11004 | | // Copyright Casey Carter 2015 |
11005 | | |
11006 | | #ifndef NANORANGE_ALGORITHM_MINMAX_ELEMENT_HPP_INCLUDED |
11007 | | #define NANORANGE_ALGORITHM_MINMAX_ELEMENT_HPP_INCLUDED |
11008 | | |
11009 | | NANO_BEGIN_NAMESPACE |
11010 | | |
11011 | | template <typename T> |
11012 | | using minmax_element_result = min_max_result<T>; |
11013 | | |
11014 | | namespace detail { |
11015 | | |
11016 | | struct minmax_element_fn { |
11017 | | private: |
11018 | | template <typename I, typename S, typename Comp, typename Proj> |
11019 | | static constexpr minmax_element_result<I> impl(I first, |
11020 | | S last, |
11021 | | Comp& comp, |
11022 | | Proj& proj) |
11023 | | { |
11024 | | minmax_element_result<I> result{first, first}; |
11025 | | |
11026 | | if (first == last || ++first == last) { |
11027 | | return result; |
11028 | | } |
11029 | | |
11030 | | if (nano::invoke(comp, nano::invoke(proj, *first), |
11031 | | nano::invoke(proj, *result.min))) { |
11032 | | result.min = first; |
11033 | | } |
11034 | | else if (!nano::invoke(comp, nano::invoke(proj, *first), |
11035 | | nano::invoke(proj, *result.max))) { |
11036 | | result.max = first; |
11037 | | } |
11038 | | |
11039 | | while (++first != last) { |
11040 | | I it = first; |
11041 | | |
11042 | | // Last iteration |
11043 | | if (++first == last) { |
11044 | | if (nano::invoke(comp, nano::invoke(proj, *it), |
11045 | | nano::invoke(proj, *result.min))) { |
11046 | | result.min = std::move(it); |
11047 | | } |
11048 | | else if (!nano::invoke(comp, nano::invoke(proj, *it), |
11049 | | nano::invoke(proj, *result.max))) { |
11050 | | result.max = std::move(it); |
11051 | | } |
11052 | | break; |
11053 | | } |
11054 | | |
11055 | | if (nano::invoke(comp, nano::invoke(proj, *first), |
11056 | | nano::invoke(proj, *it))) { |
11057 | | if (nano::invoke(comp, nano::invoke(proj, *first), |
11058 | | nano::invoke(proj, *result.min))) { |
11059 | | result.min = first; |
11060 | | } |
11061 | | if (!nano::invoke(comp, nano::invoke(proj, *it), |
11062 | | nano::invoke(proj, *result.max))) { |
11063 | | result.max = it; |
11064 | | } |
11065 | | } |
11066 | | else { |
11067 | | if (nano::invoke(comp, nano::invoke(proj, *it), |
11068 | | nano::invoke(proj, *result.min))) { |
11069 | | result.min = it; |
11070 | | } |
11071 | | if (!nano::invoke(comp, nano::invoke(proj, *first), |
11072 | | nano::invoke(proj, *result.max))) { |
11073 | | result.max = first; |
11074 | | } |
11075 | | } |
11076 | | } |
11077 | | |
11078 | | return result; |
11079 | | } |
11080 | | |
11081 | | public: |
11082 | | template <typename I, |
11083 | | typename S, |
11084 | | typename Comp = ranges::less, |
11085 | | typename Proj = identity> |
11086 | | constexpr std::enable_if_t< |
11087 | | forward_iterator<I> && sentinel_for<S, I> && |
11088 | | indirect_strict_weak_order<Comp, projected<I, Proj>>, |
11089 | | minmax_element_result<I>> |
11090 | | operator()(I first, |
11091 | | S last, |
11092 | | Comp comp = Comp{}, |
11093 | | Proj proj = Proj{}) const |
11094 | | { |
11095 | | return minmax_element_fn::impl(std::move(first), std::move(last), |
11096 | | comp, proj); |
11097 | | } |
11098 | | |
11099 | | template <typename Rng, |
11100 | | typename Comp = ranges::less, |
11101 | | typename Proj = identity> |
11102 | | constexpr std::enable_if_t< |
11103 | | forward_range<Rng> && |
11104 | | indirect_strict_weak_order<Comp, |
11105 | | projected<iterator_t<Rng>, Proj>>, |
11106 | | minmax_element_result<borrowed_iterator_t<Rng>>> |
11107 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
11108 | | { |
11109 | | return minmax_element_fn::impl(nano::begin(rng), nano::end(rng), |
11110 | | comp, proj); |
11111 | | } |
11112 | | }; |
11113 | | |
11114 | | } // namespace detail |
11115 | | |
11116 | | NANO_INLINE_VAR(detail::minmax_element_fn, minmax_element) |
11117 | | |
11118 | | NANO_END_NAMESPACE |
11119 | | |
11120 | | #endif |
11121 | | |
11122 | | // nanorange/algorithm/next_permutation.hpp |
11123 | | // |
11124 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11125 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11126 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11127 | | |
11128 | | // Taken from Range-V3 |
11129 | | // |
11130 | | // Copyright Eric Niebler 2014-2018 |
11131 | | // |
11132 | | //===-------------------------- algorithm ---------------------------------===// |
11133 | | // |
11134 | | // The LLVM Compiler Infrastructure |
11135 | | // |
11136 | | // This file is dual licensed under the MIT and the University of Illinois Open |
11137 | | // Source Licenses. See LICENSE.TXT for details. |
11138 | | // |
11139 | | //===----------------------------------------------------------------------===// |
11140 | | |
11141 | | #ifndef NANORANGE_ALGORITHM_NEXT_PERMUTATION_HPP_INCLUDED |
11142 | | #define NANORANGE_ALGORITHM_NEXT_PERMUTATION_HPP_INCLUDED |
11143 | | |
11144 | | // nanorange/algorithm/reverse.hpp |
11145 | | // |
11146 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11147 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11148 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11149 | | |
11150 | | #ifndef NANORANGE_ALGORITHM_REVERSE_HPP_INCLUDED |
11151 | | #define NANORANGE_ALGORITHM_REVERSE_HPP_INCLUDED |
11152 | | |
11153 | | NANO_BEGIN_NAMESPACE |
11154 | | |
11155 | | namespace detail { |
11156 | | |
11157 | | struct reverse_fn { |
11158 | | private: |
11159 | | template <typename I> |
11160 | | static constexpr I impl(I first, I last) |
11161 | | { |
11162 | | I ret = last; |
11163 | | while (first != last && first != --last) { |
11164 | | nano::iter_swap(first, last); |
11165 | | ++first; |
11166 | | } |
11167 | | |
11168 | | return ret; |
11169 | | } |
11170 | | |
11171 | | template <typename I, typename S> |
11172 | | static constexpr std::enable_if_t<!same_as<I, S>, I> impl(I first, |
11173 | | S bound) |
11174 | | { |
11175 | | I last = next(first, bound); |
11176 | | return reverse_fn::impl(std::move(first), std::move(last)); |
11177 | | } |
11178 | | |
11179 | | public: |
11180 | | template <typename I, typename S> |
11181 | | constexpr std:: |
11182 | | enable_if_t<bidirectional_iterator<I> && sentinel_for<S, I>, I> |
11183 | | operator()(I first, S last) const |
11184 | | { |
11185 | | return reverse_fn::impl(std::move(first), std::move(last)); |
11186 | | } |
11187 | | |
11188 | | template <typename Rng> |
11189 | | constexpr std::enable_if_t<bidirectional_range<Rng>, |
11190 | | borrowed_iterator_t<Rng>> |
11191 | | operator()(Rng&& rng) const |
11192 | | { |
11193 | | return reverse_fn::impl(nano::begin(rng), nano::end(rng)); |
11194 | | } |
11195 | | }; |
11196 | | |
11197 | | } // namespace detail |
11198 | | |
11199 | | NANO_INLINE_VAR(detail::reverse_fn, reverse) |
11200 | | |
11201 | | NANO_END_NAMESPACE |
11202 | | |
11203 | | #endif |
11204 | | |
11205 | | NANO_BEGIN_NAMESPACE |
11206 | | |
11207 | | template <typename I> |
11208 | | using next_permutation_result = in_found_result<I>; |
11209 | | |
11210 | | namespace detail { |
11211 | | |
11212 | | struct next_permutation_fn { |
11213 | | private: |
11214 | | template <typename I, typename S, typename Comp, typename Proj> |
11215 | | static constexpr next_permutation_result<I> impl(I first, |
11216 | | S last, |
11217 | | Comp& comp, |
11218 | | Proj& proj) |
11219 | | { |
11220 | | if (first == last) { |
11221 | | return {std::move(first), false}; |
11222 | | } |
11223 | | |
11224 | | I last_it = nano::next(first, last); |
11225 | | I i = last_it; |
11226 | | |
11227 | | if (first == --i) { |
11228 | | return {std::move(last_it), false}; |
11229 | | } |
11230 | | |
11231 | | while (true) { |
11232 | | I ip1 = i; |
11233 | | |
11234 | | if (nano::invoke(comp, nano::invoke(proj, *--i), |
11235 | | nano::invoke(proj, *ip1))) { |
11236 | | I j = last_it; |
11237 | | while (!nano::invoke(comp, nano::invoke(proj, *i), |
11238 | | nano::invoke(proj, *--j))) |
11239 | | ; |
11240 | | |
11241 | | nano::iter_swap(i, j); |
11242 | | nano::reverse(ip1, last_it); |
11243 | | return {std::move(last_it), true}; |
11244 | | } |
11245 | | |
11246 | | if (i == first) { |
11247 | | nano::reverse(first, last_it); |
11248 | | return {std::move(last_it), false}; |
11249 | | } |
11250 | | } |
11251 | | } |
11252 | | |
11253 | | public: |
11254 | | template <typename I, |
11255 | | typename S, |
11256 | | typename Comp = ranges::less, |
11257 | | typename Proj = identity> |
11258 | | constexpr std::enable_if_t<bidirectional_iterator<I> && |
11259 | | sentinel_for<S, I> && |
11260 | | sortable<I, Comp, Proj>, |
11261 | | next_permutation_result<I>> |
11262 | | operator()(I first, |
11263 | | S last, |
11264 | | Comp comp = Comp{}, |
11265 | | Proj proj = Proj{}) const |
11266 | | { |
11267 | | return next_permutation_fn::impl(std::move(first), std::move(last), |
11268 | | comp, proj); |
11269 | | } |
11270 | | |
11271 | | template <typename Rng, |
11272 | | typename Comp = ranges::less, |
11273 | | typename Proj = identity> |
11274 | | constexpr std::enable_if_t< |
11275 | | bidirectional_range<Rng> && sortable<iterator_t<Rng>, Comp, Proj>, |
11276 | | next_permutation_result<borrowed_iterator_t<Rng>>> |
11277 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
11278 | | { |
11279 | | return next_permutation_fn::impl(nano::begin(rng), nano::end(rng), |
11280 | | comp, proj); |
11281 | | } |
11282 | | }; |
11283 | | |
11284 | | } // namespace detail |
11285 | | |
11286 | | NANO_INLINE_VAR(detail::next_permutation_fn, next_permutation) |
11287 | | |
11288 | | NANO_END_NAMESPACE |
11289 | | |
11290 | | #endif |
11291 | | |
11292 | | // nanorange/algorithm/none_of.hpp |
11293 | | // |
11294 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11295 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11296 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11297 | | |
11298 | | #ifndef NANORANGE_ALGORITHM_NONE_OF_HPP_INCLUDED |
11299 | | #define NANORANGE_ALGORITHM_NONE_OF_HPP_INCLUDED |
11300 | | |
11301 | | NANO_BEGIN_NAMESPACE |
11302 | | |
11303 | | // [ranges.alg.none_of] |
11304 | | |
11305 | | namespace detail { |
11306 | | |
11307 | | struct none_of_fn { |
11308 | | template <typename I, |
11309 | | typename S, |
11310 | | typename Proj = identity, |
11311 | | typename Pred> |
11312 | | constexpr std::enable_if_t< |
11313 | | input_iterator<I> && sentinel_for<S, I> && |
11314 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
11315 | | bool> |
11316 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
11317 | | { |
11318 | | return !any_of_fn::impl(first, last, pred, proj); |
11319 | | } |
11320 | | |
11321 | | template <typename Rng, typename Proj = identity, typename Pred> |
11322 | | constexpr std::enable_if_t< |
11323 | | input_range<Rng> && |
11324 | | indirect_unary_predicate<Pred, |
11325 | | projected<iterator_t<Rng>, Proj>>, |
11326 | | bool> |
11327 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
11328 | | { |
11329 | | return !any_of_fn::impl(nano::begin(rng), nano::end(rng), pred, |
11330 | | proj); |
11331 | | } |
11332 | | }; |
11333 | | |
11334 | | } // namespace detail |
11335 | | |
11336 | | NANO_INLINE_VAR(detail::none_of_fn, none_of) |
11337 | | |
11338 | | NANO_END_NAMESPACE |
11339 | | |
11340 | | #endif |
11341 | | // nanorange/algorithm/nth_element.hpp |
11342 | | // |
11343 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
11344 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11345 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11346 | | |
11347 | | // Uses code from cmcstl2 - A concept-enabled C++ standard library |
11348 | | // |
11349 | | // Copyright Eric Niebler 2014 |
11350 | | // Copyright Casey Carter 2015 |
11351 | | // |
11352 | | |
11353 | | // |
11354 | | //===----------------------------------------------------------------------===// |
11355 | | // |
11356 | | // The LLVM Compiler Infrastructure |
11357 | | // |
11358 | | // This file is dual licensed under the MIT and the University of Illinois Open |
11359 | | // Source Licenses. See LICENSE.TXT for details. |
11360 | | // |
11361 | | //===----------------------------------------------------------------------===// |
11362 | | |
11363 | | #ifndef NANORANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED |
11364 | | #define NANORANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED |
11365 | | |
11366 | | NANO_BEGIN_NAMESPACE |
11367 | | |
11368 | | namespace detail { |
11369 | | |
11370 | | struct nth_element_fn { |
11371 | | private: |
11372 | | template <typename I, typename Comp, typename Proj> |
11373 | | static constexpr void impl(I first, |
11374 | | I nth, |
11375 | | I last, |
11376 | | Comp& comp, |
11377 | | Proj& proj) |
11378 | | { |
11379 | | constexpr iter_difference_t<I> limit = 7; |
11380 | | |
11381 | | const auto pred = [&comp, &proj](auto&& t, auto&& u) { |
11382 | | return nano::invoke( |
11383 | | comp, nano::invoke(proj, std::forward<decltype(t)>(t)), |
11384 | | nano::invoke(proj, std::forward<decltype(u)>(u))); |
11385 | | }; |
11386 | | |
11387 | | I end = last; |
11388 | | |
11389 | | while (true) { |
11390 | | if (nth == end) |
11391 | | return; |
11392 | | |
11393 | | iter_difference_t<I> len = end - first; |
11394 | | |
11395 | | switch (len) { |
11396 | | case 0: |
11397 | | case 1: |
11398 | | return; |
11399 | | case 2: |
11400 | | if (pred(*--end, *first)) |
11401 | | iter_swap(first, end); |
11402 | | return; |
11403 | | case 3: { |
11404 | | I m = first; |
11405 | | sort3(first, ++m, --end, comp, proj); |
11406 | | return; |
11407 | | } |
11408 | | default: |
11409 | | break; |
11410 | | } |
11411 | | if (len <= limit) { |
11412 | | selection_sort(first, end, comp, proj); |
11413 | | return; |
11414 | | } |
11415 | | // Post: len > limit |
11416 | | |
11417 | | I m = first + len / 2; |
11418 | | I lm1 = end; |
11419 | | unsigned n_swaps = sort3(first, m, --lm1, comp, proj); |
11420 | | // Post: *m is median |
11421 | | |
11422 | | // partition [first, m) < *m and *m <= [m, end) |
11423 | | //(this inhibits tossing elements equivalent to m around |
11424 | | //unnecessarily) |
11425 | | I i = first; |
11426 | | I j = lm1; |
11427 | | // j points beyond range to be tested, *lm1 is known to be <= *m |
11428 | | // The search going up is known to be guarded but the search |
11429 | | // coming down isn't. Prime the downward search with a guard. |
11430 | | if (!pred(*i, *m)) { // if *first == *m |
11431 | | // *first == *m, *first doesn't go in first part |
11432 | | // manually guard downward moving j against i |
11433 | | bool restart = false; |
11434 | | while (true) { |
11435 | | if (i == --j) { |
11436 | | // *first == *m, *m <= all other elements |
11437 | | // Parition instead into [first, i) == *first and |
11438 | | // *first < [i, end) |
11439 | | ++i; // first + 1 |
11440 | | j = end; |
11441 | | if (!pred(*first, *--j)) { // we need a guard if |
11442 | | // *first == *(end-1) |
11443 | | while (true) { |
11444 | | if (i == j) { |
11445 | | return; // [first, end) all equivalent |
11446 | | // elements |
11447 | | } |
11448 | | if (pred(*first, *i)) { |
11449 | | iter_swap(i, j); |
11450 | | ++n_swaps; |
11451 | | ++i; |
11452 | | break; |
11453 | | } |
11454 | | ++i; |
11455 | | } |
11456 | | } |
11457 | | // [first, i) == *first and *first < [j, end) and j |
11458 | | // == end - 1 |
11459 | | if (i == j) |
11460 | | return; |
11461 | | |
11462 | | while (true) { |
11463 | | while (!pred(*first, *i)) { |
11464 | | ++i; |
11465 | | } |
11466 | | while (pred(*first, *--j)) {} |
11467 | | if (i >= j) |
11468 | | break; |
11469 | | iter_swap(i, j); |
11470 | | ++n_swaps; |
11471 | | ++i; |
11472 | | } |
11473 | | // [first, i) == *first and *first < [i, end) |
11474 | | // The first part is sorted, |
11475 | | if (nth < i) |
11476 | | return; |
11477 | | |
11478 | | // nth_element the second part |
11479 | | // nth_element<C>(i, nth, end, comp); |
11480 | | restart = true; |
11481 | | break; |
11482 | | } |
11483 | | if (pred(*j, *m)) { |
11484 | | iter_swap(i, j); |
11485 | | ++n_swaps; |
11486 | | break; // found guard for downward moving j, now |
11487 | | // use unguarded partition |
11488 | | } |
11489 | | } |
11490 | | if (restart) { |
11491 | | first = i; |
11492 | | continue; |
11493 | | } |
11494 | | } |
11495 | | ++i; |
11496 | | // j points beyond range to be tested, *lm1 is known to be <= *m |
11497 | | // if not yet partitioned... |
11498 | | if (i < j) { |
11499 | | // known that *(i - 1) < *m |
11500 | | while (true) { |
11501 | | // m still guards upward moving i |
11502 | | while (pred(*i, *m)) { |
11503 | | ++i; |
11504 | | } |
11505 | | // It is now known that a guard exists for downward |
11506 | | // moving j |
11507 | | while (!pred(*--j, *m)) {} |
11508 | | if (i >= j) |
11509 | | break; |
11510 | | iter_swap(i, j); |
11511 | | ++n_swaps; |
11512 | | // It is known that m != j |
11513 | | // If m just moved, follow it |
11514 | | if (m == i) |
11515 | | m = j; |
11516 | | ++i; |
11517 | | } |
11518 | | } |
11519 | | // [first, i) < *m and *m <= [i, end) |
11520 | | if (i != m && pred(*m, *i)) { |
11521 | | iter_swap(i, m); |
11522 | | ++n_swaps; |
11523 | | } |
11524 | | // [first, i) < *i and *i <= [i+1, end) |
11525 | | if (nth == i) |
11526 | | return; |
11527 | | |
11528 | | if (n_swaps == 0) { |
11529 | | // We were given a perfectly partitioned sequence. |
11530 | | // Coincidence? |
11531 | | if (nth < i) { |
11532 | | // Check for [first, i) already sorted |
11533 | | j = m = first; |
11534 | | while (true) { |
11535 | | if (++j == i) { |
11536 | | // [first, i) sorted |
11537 | | return; |
11538 | | } |
11539 | | if (pred(*j, *m)) { |
11540 | | // not yet sorted, so sort |
11541 | | break; |
11542 | | } |
11543 | | m = j; |
11544 | | } |
11545 | | } |
11546 | | else { |
11547 | | // Check for [i, end) already sorted |
11548 | | j = m = i; |
11549 | | while (true) { |
11550 | | if (++j == end) { |
11551 | | // [i, end) sorted |
11552 | | return; |
11553 | | } |
11554 | | if (pred(*j, *m)) { |
11555 | | // not yet sorted, so sort |
11556 | | break; |
11557 | | } |
11558 | | m = j; |
11559 | | } |
11560 | | } |
11561 | | } |
11562 | | |
11563 | | // nth_element on range containing nth |
11564 | | if (nth < i) { |
11565 | | // nth_element<C>(first, nth, i, comp); |
11566 | | end = i; |
11567 | | } |
11568 | | else { |
11569 | | // nth_element<C>(i+1, nth, end, comp); |
11570 | | first = ++i; |
11571 | | } |
11572 | | } |
11573 | | } |
11574 | | |
11575 | | template <typename I, typename Comp, typename Proj> |
11576 | | static constexpr unsigned sort3(I x, I y, I z, Comp& comp, Proj& proj) |
11577 | | { |
11578 | | const auto pred = [&comp, &proj](auto&& t, auto&& u) { |
11579 | | return nano::invoke( |
11580 | | comp, nano::invoke(proj, std::forward<decltype(t)>(t)), |
11581 | | nano::invoke(proj, std::forward<decltype(u)>(u))); |
11582 | | }; |
11583 | | |
11584 | | if (!pred(*y, *x)) { // if x <= y |
11585 | | if (!pred(*z, *y)) { // if y <= z |
11586 | | return 0; // x <= y && y <= z |
11587 | | } |
11588 | | // x <= y && y > z |
11589 | | iter_swap(y, z); // x <= z && y < z |
11590 | | if (pred(*y, *x)) { // if x > y |
11591 | | iter_swap(x, y); // x < y && y <= z |
11592 | | return 2; |
11593 | | } |
11594 | | return 1; // x <= y && y < z |
11595 | | } |
11596 | | if (pred(*z, *y)) { // x > y, if y > z |
11597 | | iter_swap(x, z); // x < y && y < z |
11598 | | return 1; |
11599 | | } |
11600 | | iter_swap(x, y); // x > y && y <= z |
11601 | | // x < y && x <= z |
11602 | | if (pred(*z, *y)) { // if y > z |
11603 | | iter_swap(y, z); // x <= y && y < z |
11604 | | return 2; |
11605 | | } |
11606 | | return 1; |
11607 | | } |
11608 | | |
11609 | | template <typename I, typename Comp, typename Proj> |
11610 | | static constexpr void selection_sort(I first, |
11611 | | I last, |
11612 | | Comp& comp, |
11613 | | Proj& proj) |
11614 | | { |
11615 | | for (I lm1 = prev(last); first != lm1; ++first) { |
11616 | | I i = min_element_fn::impl(first, last, comp, proj); |
11617 | | if (i != first) { |
11618 | | iter_swap(first, i); |
11619 | | } |
11620 | | } |
11621 | | } |
11622 | | |
11623 | | public: |
11624 | | template <typename I, |
11625 | | typename S, |
11626 | | typename Comp = ranges::less, |
11627 | | typename Proj = identity> |
11628 | | std::enable_if_t<random_access_iterator<I> && sentinel_for<S, I> && |
11629 | | sortable<I, Comp, Proj>, |
11630 | | I> constexpr |
11631 | | operator()(I first, |
11632 | | I nth, |
11633 | | S last, |
11634 | | Comp comp = Comp{}, |
11635 | | Proj proj = Proj{}) const |
11636 | | { |
11637 | | const I ilast = nano::next(nth, last); |
11638 | | impl(std::move(first), nth, std::move(ilast), comp, proj); |
11639 | | return ilast; |
11640 | | } |
11641 | | |
11642 | | template <typename Rng, |
11643 | | typename Comp = ranges::less, |
11644 | | typename Proj = identity> |
11645 | | std::enable_if_t<random_access_range<Rng> && |
11646 | | sortable<iterator_t<Rng>, Comp, Proj>, |
11647 | | borrowed_iterator_t<Rng>> constexpr |
11648 | | operator()(Rng&& rng, |
11649 | | iterator_t<Rng> nth, |
11650 | | Comp comp = Comp{}, |
11651 | | Proj proj = Proj{}) const |
11652 | | { |
11653 | | const auto last = nano::next(nth, nano::end(rng)); |
11654 | | impl(nano::begin(rng), std::move(nth), last, comp, proj); |
11655 | | return last; |
11656 | | } |
11657 | | }; |
11658 | | |
11659 | | } // namespace detail |
11660 | | |
11661 | | NANO_INLINE_VAR(detail::nth_element_fn, nth_element) |
11662 | | |
11663 | | NANO_END_NAMESPACE |
11664 | | |
11665 | | #endif |
11666 | | |
11667 | | // nanorange/algorithm/partial_sort.hpp |
11668 | | // |
11669 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11670 | | // Copyright Eric Niebler 2014 |
11671 | | // Copyright Casey Carter 2015 |
11672 | | // |
11673 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11674 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11675 | | |
11676 | | #ifndef NANORANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED |
11677 | | #define NANORANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED |
11678 | | |
11679 | | // nanorange/algorithm/sort_heap.hpp |
11680 | | // |
11681 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11682 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11683 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11684 | | |
11685 | | #ifndef NANORANGE_ALGORITHM_SORT_HEAP_HPP_INCLUDED |
11686 | | #define NANORANGE_ALGORITHM_SORT_HEAP_HPP_INCLUDED |
11687 | | |
11688 | | // nanorange/algorithm/pop_heap.hpp |
11689 | | // |
11690 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11691 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11692 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11693 | | |
11694 | | #ifndef NANORANGE_ALGORITHM_POP_HEAP_HPP_INCLUDED |
11695 | | #define NANORANGE_ALGORITHM_POP_HEAP_HPP_INCLUDED |
11696 | | |
11697 | | NANO_BEGIN_NAMESPACE |
11698 | | |
11699 | | namespace detail { |
11700 | | |
11701 | | struct pop_heap_fn { |
11702 | | private: |
11703 | | friend struct sort_heap_fn; |
11704 | | |
11705 | | template <typename I, typename Comp, typename Proj> |
11706 | | static constexpr I impl(I first, |
11707 | | iter_difference_t<I> n, |
11708 | | Comp& comp, |
11709 | | Proj& proj) |
11710 | 3.79k | { |
11711 | 3.79k | if (n > 1) { |
11712 | 3.79k | nano::iter_swap(first, first + (n - 1)); |
11713 | 3.79k | detail::sift_down_n(first, n - 1, first, comp, proj); |
11714 | 3.79k | } |
11715 | | |
11716 | 3.79k | return first + n; |
11717 | 3.79k | } |
11718 | | |
11719 | | public: |
11720 | | template <typename I, |
11721 | | typename S, |
11722 | | typename Comp = ranges::less, |
11723 | | typename Proj = identity> |
11724 | | constexpr std::enable_if_t<random_access_iterator<I> && |
11725 | | sentinel_for<S, I> && |
11726 | | sortable<I, Comp, Proj>, |
11727 | | I> |
11728 | | operator()(I first, |
11729 | | S last, |
11730 | | Comp comp = Comp{}, |
11731 | | Proj proj = Proj{}) const |
11732 | | { |
11733 | | const auto n = nano::distance(first, last); |
11734 | | return pop_heap_fn::impl(std::move(first), n, comp, proj); |
11735 | | } |
11736 | | |
11737 | | template <typename Rng, |
11738 | | typename Comp = ranges::less, |
11739 | | typename Proj = identity> |
11740 | | constexpr std::enable_if_t<random_access_range<Rng> && |
11741 | | sortable<iterator_t<Rng>, Comp, Proj>, |
11742 | | borrowed_iterator_t<Rng>> |
11743 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
11744 | | { |
11745 | | return pop_heap_fn::impl(nano::begin(rng), nano::distance(rng), |
11746 | | comp, proj); |
11747 | | } |
11748 | | }; |
11749 | | |
11750 | | } // namespace detail |
11751 | | |
11752 | | NANO_INLINE_VAR(detail::pop_heap_fn, pop_heap) |
11753 | | |
11754 | | NANO_END_NAMESPACE |
11755 | | |
11756 | | #endif |
11757 | | |
11758 | | NANO_BEGIN_NAMESPACE |
11759 | | |
11760 | | namespace detail { |
11761 | | |
11762 | | struct sort_heap_fn { |
11763 | | private: |
11764 | | template <typename I, typename Comp, typename Proj> |
11765 | | static constexpr I impl(I first, |
11766 | | iter_difference_t<I> n, |
11767 | | Comp& comp, |
11768 | | Proj& proj) |
11769 | 162 | { |
11770 | 162 | if (n < 2) { |
11771 | 0 | return first + n; |
11772 | 0 | } |
11773 | | |
11774 | 3.96k | for (auto i = n; i > 1; --i) { |
11775 | 3.79k | pop_heap_fn::impl(first, i, comp, proj); |
11776 | 3.79k | } |
11777 | | |
11778 | 162 | return first + n; |
11779 | 162 | } |
11780 | | |
11781 | | public: |
11782 | | template <typename I, |
11783 | | typename S, |
11784 | | typename Comp = ranges::less, |
11785 | | typename Proj = identity> |
11786 | | constexpr std::enable_if_t<random_access_iterator<I> && |
11787 | | sentinel_for<S, I> && |
11788 | | sortable<I, Comp, Proj>, |
11789 | | I> |
11790 | | operator()(I first, |
11791 | | S last, |
11792 | | Comp comp = Comp{}, |
11793 | | Proj proj = Proj{}) const |
11794 | 162 | { |
11795 | 162 | const auto n = nano::distance(first, last); |
11796 | 162 | return sort_heap_fn::impl(std::move(first), n, comp, proj); |
11797 | 162 | } |
11798 | | |
11799 | | template <typename Rng, |
11800 | | typename Comp = ranges::less, |
11801 | | typename Proj = identity> |
11802 | | constexpr std::enable_if_t<random_access_range<Rng> && |
11803 | | sortable<iterator_t<Rng>, Comp, Proj>, |
11804 | | borrowed_iterator_t<Rng>> |
11805 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
11806 | | { |
11807 | | return sort_heap_fn::impl(nano::begin(rng), nano::distance(rng), |
11808 | | comp, proj); |
11809 | | } |
11810 | | }; |
11811 | | |
11812 | | } // namespace detail |
11813 | | |
11814 | | NANO_INLINE_VAR(detail::sort_heap_fn, sort_heap) |
11815 | | |
11816 | | NANO_END_NAMESPACE |
11817 | | |
11818 | | #endif |
11819 | | |
11820 | | NANO_BEGIN_NAMESPACE |
11821 | | |
11822 | | namespace detail { |
11823 | | |
11824 | | struct partial_sort_fn { |
11825 | | private: |
11826 | | template <typename I, typename S, typename Comp, typename Proj> |
11827 | | static constexpr I impl(I first, |
11828 | | I middle, |
11829 | | S last, |
11830 | | Comp& comp, |
11831 | | Proj& proj) |
11832 | | { |
11833 | | nano::make_heap(first, middle, comp, proj); |
11834 | | const auto len = nano::distance(first, middle); |
11835 | | I i = middle; |
11836 | | |
11837 | | while (i != last) { |
11838 | | if (nano::invoke(comp, nano::invoke(proj, *i), |
11839 | | nano::invoke(proj, *first))) { |
11840 | | nano::iter_swap(i, first); |
11841 | | detail::sift_down_n(first, len, first, comp, proj); |
11842 | | } |
11843 | | ++i; |
11844 | | } |
11845 | | nano::sort_heap(first, middle, comp, proj); |
11846 | | return i; |
11847 | | } |
11848 | | |
11849 | | public: |
11850 | | template <typename I, |
11851 | | typename S, |
11852 | | typename Comp = ranges::less, |
11853 | | typename Proj = identity> |
11854 | | constexpr std::enable_if_t<random_access_iterator<I> && |
11855 | | sentinel_for<S, I> && |
11856 | | sortable<I, Comp, Proj>, |
11857 | | I> |
11858 | | operator()(I first, |
11859 | | I middle, |
11860 | | S last, |
11861 | | Comp comp = Comp{}, |
11862 | | Proj proj = Proj{}) const |
11863 | | { |
11864 | | return partial_sort_fn::impl(std::move(first), std::move(middle), |
11865 | | std::move(last), comp, proj); |
11866 | | } |
11867 | | |
11868 | | template <typename Rng, |
11869 | | typename Comp = ranges::less, |
11870 | | typename Proj = identity> |
11871 | | constexpr std::enable_if_t<random_access_range<Rng> && |
11872 | | sortable<iterator_t<Rng>, Comp, Proj>, |
11873 | | borrowed_iterator_t<Rng>> |
11874 | | operator()(Rng&& rng, |
11875 | | iterator_t<Rng> middle, |
11876 | | Comp comp = Comp{}, |
11877 | | Proj proj = Proj{}) const |
11878 | | { |
11879 | | return partial_sort_fn::impl(nano::begin(rng), std::move(middle), |
11880 | | nano::end(rng), comp, proj); |
11881 | | } |
11882 | | }; |
11883 | | |
11884 | | } // namespace detail |
11885 | | |
11886 | | NANO_INLINE_VAR(detail::partial_sort_fn, partial_sort) |
11887 | | |
11888 | | NANO_END_NAMESPACE |
11889 | | |
11890 | | #endif |
11891 | | |
11892 | | // nanorange/algorithm/partial_sort_copy.hpp |
11893 | | // |
11894 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
11895 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
11896 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
11897 | | |
11898 | | #ifndef NANORANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED |
11899 | | #define NANORANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED |
11900 | | |
11901 | | NANO_BEGIN_NAMESPACE |
11902 | | |
11903 | | template <typename I, typename O> |
11904 | | using partial_sort_copy_result = in_out_result<I, O>; |
11905 | | |
11906 | | namespace detail { |
11907 | | |
11908 | | struct partial_sort_copy_fn { |
11909 | | private: |
11910 | | template <typename I1, |
11911 | | typename S1, |
11912 | | typename I2, |
11913 | | typename S2, |
11914 | | typename Comp, |
11915 | | typename Proj1, |
11916 | | typename Proj2> |
11917 | | static constexpr partial_sort_copy_result<I1, I2> impl(I1 first, |
11918 | | S1 last, |
11919 | | I2 result_first, |
11920 | | S2 result_last, |
11921 | | Comp& comp, |
11922 | | Proj1& proj1, |
11923 | | Proj2& proj2) |
11924 | | { |
11925 | | I2 r = result_first; |
11926 | | if (r == result_last) { |
11927 | | // std::move(nano::next()) is needed to avoid GCC ICE. |
11928 | | return {std::move(nano::next(first, last)), |
11929 | | std::move(result_first)}; |
11930 | | } |
11931 | | |
11932 | | while (r != result_last && first != last) { |
11933 | | *r = *first; |
11934 | | ++r; |
11935 | | ++first; |
11936 | | } |
11937 | | |
11938 | | nano::make_heap(result_first, r, comp, proj2); |
11939 | | const auto len = nano::distance(result_first, r); |
11940 | | |
11941 | | while (first != last) { |
11942 | | iter_reference_t<I1>&& x = *first; |
11943 | | if (nano::invoke(comp, nano::invoke(proj1, x), |
11944 | | nano::invoke(proj2, *result_first))) { |
11945 | | *result_first = std::forward<iter_reference_t<I1>>(x); |
11946 | | detail::sift_down_n(result_first, len, result_first, comp, |
11947 | | proj2); |
11948 | | } |
11949 | | ++first; |
11950 | | } |
11951 | | |
11952 | | nano::sort_heap(result_first, r, comp, proj2); |
11953 | | |
11954 | | return {std::move(first), std::move(r)}; |
11955 | | } |
11956 | | |
11957 | | public: |
11958 | | template <typename I1, |
11959 | | typename S1, |
11960 | | typename I2, |
11961 | | typename S2, |
11962 | | typename Comp = ranges::less, |
11963 | | typename Proj1 = identity, |
11964 | | typename Proj2 = identity> |
11965 | | constexpr std::enable_if_t< |
11966 | | input_iterator<I1> && sentinel_for<S1, I1> && |
11967 | | random_access_iterator<I2> && sentinel_for<S2, I2> && |
11968 | | indirectly_copyable<I1, I2> && sortable<I2, Comp, Proj2> && |
11969 | | indirect_strict_weak_order<Comp, |
11970 | | projected<I1, Proj1>, |
11971 | | projected<I2, Proj2>>, |
11972 | | partial_sort_copy_result<I1, I2>> |
11973 | | operator()(I1 first, |
11974 | | S1 last, |
11975 | | I2 result_first, |
11976 | | S2 result_last, |
11977 | | Comp comp = Comp{}, |
11978 | | Proj1 proj1 = Proj1{}, |
11979 | | Proj2 proj2 = Proj2{}) const |
11980 | | { |
11981 | | return partial_sort_copy_fn::impl( |
11982 | | std::move(first), std::move(last), std::move(result_first), |
11983 | | std::move(result_last), comp, proj1, proj2); |
11984 | | } |
11985 | | |
11986 | | template <typename Rng1, |
11987 | | typename Rng2, |
11988 | | typename Comp = ranges::less, |
11989 | | typename Proj1 = identity, |
11990 | | typename Proj2 = identity> |
11991 | | constexpr std::enable_if_t< |
11992 | | input_range<Rng1> && random_access_range<Rng2> && |
11993 | | indirectly_copyable<iterator_t<Rng1>, iterator_t<Rng2>> && |
11994 | | sortable<iterator_t<Rng2>, Comp, Proj2> && |
11995 | | indirect_strict_weak_order<Comp, |
11996 | | projected<iterator_t<Rng1>, Proj1>, |
11997 | | projected<iterator_t<Rng2>, Proj2>>, |
11998 | | partial_sort_copy_result<borrowed_iterator_t<Rng1>, |
11999 | | borrowed_iterator_t<Rng2>>> |
12000 | | operator()(Rng1&& rng, |
12001 | | Rng2&& result_rng, |
12002 | | Comp comp = Comp{}, |
12003 | | Proj1 proj1 = Proj1{}, |
12004 | | Proj2 proj2 = Proj2{}) const |
12005 | | { |
12006 | | return partial_sort_copy_fn::impl( |
12007 | | nano::begin(rng), nano::end(rng), nano::begin(result_rng), |
12008 | | nano::end(result_rng), comp, proj1, proj2); |
12009 | | } |
12010 | | }; |
12011 | | |
12012 | | } // namespace detail |
12013 | | |
12014 | | NANO_INLINE_VAR(detail::partial_sort_copy_fn, partial_sort_copy) |
12015 | | |
12016 | | NANO_END_NAMESPACE |
12017 | | |
12018 | | #endif |
12019 | | |
12020 | | // nanorange/algorithm/partition.hpp |
12021 | | // |
12022 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12023 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12024 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12025 | | |
12026 | | #ifndef NANORANGE_ALGORITHM_PARTITION_HPP_INCLUDED |
12027 | | #define NANORANGE_ALGORITHM_PARTITION_HPP_INCLUDED |
12028 | | |
12029 | | NANO_BEGIN_NAMESPACE |
12030 | | |
12031 | | namespace detail { |
12032 | | |
12033 | | struct partition_fn { |
12034 | | private: |
12035 | | template <typename I, typename S, typename Pred, typename Proj> |
12036 | | static constexpr subrange<I> impl(I first, |
12037 | | S last, |
12038 | | Pred& pred, |
12039 | | Proj& proj) |
12040 | | { |
12041 | | I it = nano::find_if_not(first, last, pred, proj); |
12042 | | |
12043 | | if (it == last) { |
12044 | | return {std::move(it), std::move(nano::next(first, last))}; |
12045 | | } |
12046 | | |
12047 | | auto n = nano::next(it); |
12048 | | |
12049 | | while (n != last) { |
12050 | | if (nano::invoke(pred, nano::invoke(proj, *n))) { |
12051 | | nano::iter_swap(n, it); |
12052 | | ++it; |
12053 | | } |
12054 | | ++n; |
12055 | | } |
12056 | | |
12057 | | return {std::move(it), std::move(n)}; |
12058 | | } |
12059 | | |
12060 | | public: |
12061 | | template <typename I, |
12062 | | typename S, |
12063 | | typename Pred, |
12064 | | typename Proj = identity> |
12065 | | constexpr std::enable_if_t< |
12066 | | forward_iterator<I> && sentinel_for<S, I> && |
12067 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
12068 | | subrange<I>> |
12069 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
12070 | | { |
12071 | | return partition_fn::impl(std::move(first), std::move(last), pred, |
12072 | | proj); |
12073 | | } |
12074 | | |
12075 | | template <typename Rng, typename Pred, typename Proj = identity> |
12076 | | constexpr std::enable_if_t< |
12077 | | forward_range<Rng> && |
12078 | | indirect_unary_predicate<Pred, |
12079 | | projected<iterator_t<Rng>, Proj>>, |
12080 | | borrowed_subrange_t<Rng>> |
12081 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
12082 | | { |
12083 | | return partition_fn::impl(nano::begin(rng), nano::end(rng), pred, |
12084 | | proj); |
12085 | | } |
12086 | | }; |
12087 | | |
12088 | | } // namespace detail |
12089 | | |
12090 | | NANO_INLINE_VAR(detail::partition_fn, partition) |
12091 | | |
12092 | | NANO_END_NAMESPACE |
12093 | | |
12094 | | #endif |
12095 | | |
12096 | | // nanorange/algorithm/partition_copy.hpp |
12097 | | // |
12098 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12099 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12100 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12101 | | |
12102 | | #ifndef NANORANGE_ALGORITHM_PARTITION_COPY_HPP_INCLUDED |
12103 | | #define NANORANGE_ALGORITHM_PARTITION_COPY_HPP_INCLUDED |
12104 | | |
12105 | | NANO_BEGIN_NAMESPACE |
12106 | | |
12107 | | template <typename I, typename O1, typename O2> |
12108 | | using partition_copy_result = in_out_out_result<I, O1, O2>; |
12109 | | |
12110 | | namespace detail { |
12111 | | |
12112 | | struct partition_copy_fn { |
12113 | | private: |
12114 | | template <typename I, |
12115 | | typename S, |
12116 | | typename O1, |
12117 | | typename O2, |
12118 | | typename Pred, |
12119 | | typename Proj> |
12120 | | static constexpr partition_copy_result<I, O1, O2> impl(I first, |
12121 | | S last, |
12122 | | O1 out_true, |
12123 | | O2 out_false, |
12124 | | Pred& pred, |
12125 | | Proj& proj) |
12126 | | { |
12127 | | while (first != last) { |
12128 | | auto&& val = *first; |
12129 | | if (nano::invoke(pred, nano::invoke(proj, val))) { |
12130 | | *out_true = std::forward<decltype(val)>(val); |
12131 | | ++out_true; |
12132 | | } |
12133 | | else { |
12134 | | *out_false = std::forward<decltype(val)>(val); |
12135 | | ++out_false; |
12136 | | } |
12137 | | ++first; |
12138 | | } |
12139 | | |
12140 | | return {std::move(first), std::move(out_true), |
12141 | | std::move(out_false)}; |
12142 | | } |
12143 | | |
12144 | | public: |
12145 | | template <typename I, |
12146 | | typename S, |
12147 | | typename O1, |
12148 | | typename O2, |
12149 | | typename Pred, |
12150 | | typename Proj = identity> |
12151 | | constexpr std::enable_if_t< |
12152 | | input_iterator<I> && sentinel_for<S, I> && |
12153 | | weakly_incrementable<O1> && weakly_incrementable<O2> && |
12154 | | indirect_unary_predicate<Pred, projected<I, Proj>> && |
12155 | | indirectly_copyable<I, O1> && indirectly_copyable<I, O2>, |
12156 | | partition_copy_result<I, O1, O2>> |
12157 | | operator()(I first, |
12158 | | S last, |
12159 | | O1 out_true, |
12160 | | O2 out_false, |
12161 | | Pred pred, |
12162 | | Proj proj = Proj{}) const |
12163 | | { |
12164 | | return partition_copy_fn::impl(std::move(first), std::move(last), |
12165 | | std::move(out_true), |
12166 | | std::move(out_false), pred, proj); |
12167 | | } |
12168 | | |
12169 | | template <typename Rng, |
12170 | | typename O1, |
12171 | | typename O2, |
12172 | | typename Pred, |
12173 | | typename Proj = identity> |
12174 | | constexpr std::enable_if_t< |
12175 | | input_range<Rng> && weakly_incrementable<O1> && |
12176 | | weakly_incrementable<O2> && |
12177 | | indirect_unary_predicate<Pred, |
12178 | | projected<iterator_t<Rng>, Proj>> && |
12179 | | indirectly_copyable<iterator_t<Rng>, O1> && |
12180 | | indirectly_copyable<iterator_t<Rng>, O2>, |
12181 | | partition_copy_result<borrowed_iterator_t<Rng>, O1, O2>> |
12182 | | operator()(Rng&& rng, |
12183 | | O1 out_true, |
12184 | | O2 out_false, |
12185 | | Pred pred, |
12186 | | Proj proj = Proj{}) const |
12187 | | { |
12188 | | return partition_copy_fn::impl(nano::begin(rng), nano::end(rng), |
12189 | | std::move(out_true), |
12190 | | std::move(out_false), pred, proj); |
12191 | | } |
12192 | | }; |
12193 | | |
12194 | | } // namespace detail |
12195 | | |
12196 | | NANO_INLINE_VAR(detail::partition_copy_fn, partition_copy) |
12197 | | |
12198 | | NANO_END_NAMESPACE |
12199 | | |
12200 | | #endif |
12201 | | |
12202 | | // nanorange/algorithm/prev_permutation.hpp |
12203 | | // |
12204 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12205 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12206 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12207 | | |
12208 | | // Taken from Range-V3 |
12209 | | // |
12210 | | // Copyright Eric Niebler 2014-2018 |
12211 | | // |
12212 | | //===-------------------------- algorithm ---------------------------------===// |
12213 | | // |
12214 | | // The LLVM Compiler Infrastructure |
12215 | | // |
12216 | | // This file is dual licensed under the MIT and the University of Illinois Open |
12217 | | // Source Licenses. See LICENSE.TXT for details. |
12218 | | // |
12219 | | //===----------------------------------------------------------------------===// |
12220 | | |
12221 | | #ifndef NANORANGE_ALGORITHM_PREV_PERMUTATION_HPP_INCLUDED |
12222 | | #define NANORANGE_ALGORITHM_PREV_PERMUTATION_HPP_INCLUDED |
12223 | | |
12224 | | NANO_BEGIN_NAMESPACE |
12225 | | |
12226 | | template <typename I> |
12227 | | using prev_permutation_result = in_found_result<I>; |
12228 | | |
12229 | | namespace detail { |
12230 | | |
12231 | | struct prev_permutation_fn { |
12232 | | private: |
12233 | | template <typename I, typename S, typename Comp, typename Proj> |
12234 | | static constexpr prev_permutation_result<I> impl(I first, |
12235 | | S last, |
12236 | | Comp& comp, |
12237 | | Proj& proj) |
12238 | | { |
12239 | | if (first == last) { |
12240 | | return {std::move(first), false}; |
12241 | | } |
12242 | | |
12243 | | I last_it = nano::next(first, last); |
12244 | | I i = last_it; |
12245 | | |
12246 | | if (first == --i) { |
12247 | | return {std::move(last_it), false}; |
12248 | | } |
12249 | | |
12250 | | while (true) { |
12251 | | I ip1 = i; |
12252 | | |
12253 | | if (nano::invoke(comp, nano::invoke(proj, *ip1), |
12254 | | nano::invoke(proj, *--i))) { |
12255 | | I j = last_it; |
12256 | | |
12257 | | while (!nano::invoke(comp, nano::invoke(proj, *--j), |
12258 | | nano::invoke(proj, *i))) |
12259 | | ; |
12260 | | |
12261 | | nano::iter_swap(i, j); |
12262 | | nano::reverse(ip1, last_it); |
12263 | | return {std::move(last_it), true}; |
12264 | | } |
12265 | | |
12266 | | if (i == first) { |
12267 | | nano::reverse(first, last_it); |
12268 | | return {std::move(last_it), false}; |
12269 | | } |
12270 | | } |
12271 | | } |
12272 | | |
12273 | | public: |
12274 | | template <typename I, |
12275 | | typename S, |
12276 | | typename Comp = ranges::less, |
12277 | | typename Proj = identity> |
12278 | | constexpr std::enable_if_t<bidirectional_iterator<I> && |
12279 | | sentinel_for<S, I> && |
12280 | | sortable<I, Comp, Proj>, |
12281 | | prev_permutation_result<I>> |
12282 | | operator()(I first, |
12283 | | S last, |
12284 | | Comp comp = Comp{}, |
12285 | | Proj proj = Proj{}) const |
12286 | | { |
12287 | | return prev_permutation_fn::impl(std::move(first), std::move(last), |
12288 | | comp, proj); |
12289 | | } |
12290 | | |
12291 | | template <typename Rng, |
12292 | | typename Comp = ranges::less, |
12293 | | typename Proj = identity> |
12294 | | constexpr std::enable_if_t< |
12295 | | bidirectional_range<Rng> && sortable<iterator_t<Rng>, Comp, Proj>, |
12296 | | prev_permutation_result<borrowed_iterator_t<Rng>>> |
12297 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
12298 | | { |
12299 | | return prev_permutation_fn::impl(nano::begin(rng), nano::end(rng), |
12300 | | comp, proj); |
12301 | | } |
12302 | | }; |
12303 | | |
12304 | | } // namespace detail |
12305 | | |
12306 | | NANO_INLINE_VAR(detail::prev_permutation_fn, prev_permutation) |
12307 | | |
12308 | | NANO_END_NAMESPACE |
12309 | | |
12310 | | #endif |
12311 | | |
12312 | | // nanorange/algorithm/push_heap.hpp |
12313 | | // |
12314 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12315 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12316 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12317 | | |
12318 | | #ifndef NANORANGE_ALGORITHM_PUSH_HEAP_HPP_INCLUDED |
12319 | | #define NANORANGE_ALGORITHM_PUSH_HEAP_HPP_INCLUDED |
12320 | | |
12321 | | NANO_BEGIN_NAMESPACE |
12322 | | |
12323 | | namespace detail { |
12324 | | |
12325 | | struct push_heap_fn { |
12326 | | template <typename I, |
12327 | | typename S, |
12328 | | typename Comp = ranges::less, |
12329 | | typename Proj = identity> |
12330 | | constexpr std::enable_if_t<random_access_iterator<I> && |
12331 | | sentinel_for<S, I> && |
12332 | | sortable<I, Comp, Proj>, |
12333 | | I> |
12334 | | operator()(I first, |
12335 | | S last, |
12336 | | Comp comp = Comp{}, |
12337 | | Proj proj = Proj{}) const |
12338 | | { |
12339 | | const auto n = nano::distance(first, last); |
12340 | | detail::sift_up_n(first, n, comp, proj); |
12341 | | return first + n; |
12342 | | } |
12343 | | |
12344 | | template <typename Rng, |
12345 | | typename Comp = ranges::less, |
12346 | | typename Proj = identity> |
12347 | | constexpr std::enable_if_t<random_access_range<Rng> && |
12348 | | sortable<iterator_t<Rng>, Comp, Proj>, |
12349 | | borrowed_iterator_t<Rng>> |
12350 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
12351 | | { |
12352 | | const auto n = nano::distance(rng); |
12353 | | detail::sift_up_n(nano::begin(rng), n, comp, proj); |
12354 | | return nano::begin(rng) + n; |
12355 | | } |
12356 | | }; |
12357 | | |
12358 | | } // namespace detail |
12359 | | |
12360 | | NANO_INLINE_VAR(detail::push_heap_fn, push_heap) |
12361 | | |
12362 | | NANO_END_NAMESPACE |
12363 | | |
12364 | | #endif |
12365 | | |
12366 | | // nanorange/algorithm/remove.hpp |
12367 | | // |
12368 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12369 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12370 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12371 | | |
12372 | | #ifndef NANORANGE_ALGORITHM_REMOVE_HPP_INCLUDED |
12373 | | #define NANORANGE_ALGORITHM_REMOVE_HPP_INCLUDED |
12374 | | |
12375 | | NANO_BEGIN_NAMESPACE |
12376 | | |
12377 | | namespace detail { |
12378 | | |
12379 | | struct remove_fn { |
12380 | | private: |
12381 | | template <typename I, typename S, typename T, typename Proj> |
12382 | | static constexpr I impl(I first, S last, const T& value, Proj& proj) |
12383 | | { |
12384 | | first = nano::find(std::move(first), last, value, proj); |
12385 | | |
12386 | | if (first == last) { |
12387 | | return first; |
12388 | | } |
12389 | | |
12390 | | for (auto i = next(first); i != last; ++i) { |
12391 | | if (!(nano::invoke(proj, *i) == value)) { |
12392 | | *first = nano::iter_move(i); |
12393 | | ++first; |
12394 | | } |
12395 | | } |
12396 | | |
12397 | | return first; |
12398 | | } |
12399 | | |
12400 | | public: |
12401 | | template <typename I, typename S, typename T, typename Proj = identity> |
12402 | | constexpr std::enable_if_t<forward_iterator<I> && sentinel_for<S, I> && |
12403 | | permutable<I> && |
12404 | | indirect_relation<ranges::equal_to, |
12405 | | projected<I, Proj>, |
12406 | | const T*>, |
12407 | | I> |
12408 | | operator()(I first, S last, const T& value, Proj proj = Proj{}) const |
12409 | | { |
12410 | | return remove_fn::impl(std::move(first), std::move(last), value, |
12411 | | proj); |
12412 | | } |
12413 | | |
12414 | | template <typename Rng, typename T, typename Proj = identity> |
12415 | | constexpr std::enable_if_t< |
12416 | | forward_range<Rng> && permutable<iterator_t<Rng>> && |
12417 | | indirect_relation<ranges::equal_to, |
12418 | | projected<iterator_t<Rng>, Proj>, |
12419 | | const T*>, |
12420 | | borrowed_iterator_t<Rng>> |
12421 | | operator()(Rng&& rng, const T& value, Proj proj = Proj{}) const |
12422 | | { |
12423 | | return remove_fn::impl(nano::begin(rng), nano::end(rng), value, |
12424 | | proj); |
12425 | | } |
12426 | | }; |
12427 | | |
12428 | | } // namespace detail |
12429 | | |
12430 | | NANO_INLINE_VAR(detail::remove_fn, remove) |
12431 | | |
12432 | | NANO_END_NAMESPACE |
12433 | | |
12434 | | #endif |
12435 | | |
12436 | | // nanorange/algorithm/remove_copy.hpp |
12437 | | // |
12438 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12439 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12440 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12441 | | |
12442 | | #ifndef NANORANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED |
12443 | | #define NANORANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED |
12444 | | |
12445 | | NANO_BEGIN_NAMESPACE |
12446 | | |
12447 | | template <typename I, typename O> |
12448 | | using remove_copy_result = in_out_result<I, O>; |
12449 | | |
12450 | | namespace detail { |
12451 | | |
12452 | | struct remove_copy_fn { |
12453 | | private: |
12454 | | template <typename I, typename S, typename O, typename T, typename Proj> |
12455 | | static constexpr remove_copy_result<I, O> impl(I first, |
12456 | | S last, |
12457 | | O result, |
12458 | | const T& value, |
12459 | | Proj& proj) |
12460 | | { |
12461 | | while (first != last) { |
12462 | | auto&& ref = *first; |
12463 | | if (!(nano::invoke(proj, ref) == value)) { |
12464 | | *result = std::forward<decltype(ref)>(ref); |
12465 | | ++result; |
12466 | | } |
12467 | | ++first; |
12468 | | } |
12469 | | return {std::move(first), std::move(result)}; |
12470 | | } |
12471 | | |
12472 | | public: |
12473 | | template <typename I, |
12474 | | typename S, |
12475 | | typename O, |
12476 | | typename T, |
12477 | | typename Proj = identity> |
12478 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
12479 | | weakly_incrementable<O> && |
12480 | | indirectly_copyable<I, O> && |
12481 | | indirect_relation<ranges::equal_to, |
12482 | | projected<I, Proj>, |
12483 | | const T*>, |
12484 | | remove_copy_result<I, O>> |
12485 | | operator()(I first, |
12486 | | S last, |
12487 | | O result, |
12488 | | const T& value, |
12489 | | Proj proj = Proj{}) const |
12490 | | { |
12491 | | return remove_copy_fn::impl(std::move(first), std::move(last), |
12492 | | std::move(result), value, proj); |
12493 | | } |
12494 | | |
12495 | | template <typename Rng, |
12496 | | typename O, |
12497 | | typename T, |
12498 | | typename Proj = identity> |
12499 | | constexpr std::enable_if_t< |
12500 | | input_range<Rng> && weakly_incrementable<O> && |
12501 | | indirectly_copyable<iterator_t<Rng>, O> && |
12502 | | indirect_relation<ranges::equal_to, |
12503 | | projected<iterator_t<Rng>, Proj>, |
12504 | | const T*>, |
12505 | | remove_copy_result<borrowed_iterator_t<Rng>, O>> |
12506 | | operator()(Rng&& rng, |
12507 | | O result, |
12508 | | const T& value, |
12509 | | Proj proj = Proj{}) const |
12510 | | { |
12511 | | return remove_copy_fn::impl(nano::begin(rng), nano::end(rng), |
12512 | | std::move(result), value, proj); |
12513 | | } |
12514 | | }; |
12515 | | |
12516 | | } // namespace detail |
12517 | | |
12518 | | NANO_INLINE_VAR(detail::remove_copy_fn, remove_copy) |
12519 | | |
12520 | | NANO_END_NAMESPACE |
12521 | | |
12522 | | #endif |
12523 | | |
12524 | | // nanorange/algorithm/remove_copy_if.hpp |
12525 | | // |
12526 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12527 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12528 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12529 | | |
12530 | | #ifndef NANORANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED |
12531 | | #define NANORANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED |
12532 | | |
12533 | | NANO_BEGIN_NAMESPACE |
12534 | | |
12535 | | template <typename I, typename O> |
12536 | | using remove_copy_if_result = in_out_result<I, O>; |
12537 | | |
12538 | | namespace detail { |
12539 | | |
12540 | | struct remove_copy_if_fn { |
12541 | | private: |
12542 | | template <typename I, |
12543 | | typename S, |
12544 | | typename O, |
12545 | | typename Pred, |
12546 | | typename Proj> |
12547 | | static constexpr remove_copy_if_result<I, O> impl(I first, |
12548 | | S last, |
12549 | | O result, |
12550 | | Pred& pred, |
12551 | | Proj& proj) |
12552 | | { |
12553 | | while (first != last) { |
12554 | | auto&& ref = *first; |
12555 | | if (!nano::invoke(pred, nano::invoke(proj, ref))) { |
12556 | | *result = std::forward<decltype(ref)>(ref); |
12557 | | ++result; |
12558 | | } |
12559 | | ++first; |
12560 | | } |
12561 | | return {std::move(first), std::move(result)}; |
12562 | | } |
12563 | | |
12564 | | public: |
12565 | | template <typename I, |
12566 | | typename S, |
12567 | | typename O, |
12568 | | typename Pred, |
12569 | | typename Proj = identity> |
12570 | | constexpr std::enable_if_t< |
12571 | | input_iterator<I> && sentinel_for<S, I> && |
12572 | | weakly_incrementable<O> && indirectly_copyable<I, O> && |
12573 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
12574 | | remove_copy_if_result<I, O>> |
12575 | | operator()(I first, S last, O result, Pred pred, Proj proj = Proj{}) |
12576 | | const |
12577 | | { |
12578 | | return remove_copy_if_fn::impl(std::move(first), std::move(last), |
12579 | | std::move(result), pred, proj); |
12580 | | } |
12581 | | |
12582 | | template <typename Rng, |
12583 | | typename O, |
12584 | | typename Pred, |
12585 | | typename Proj = identity> |
12586 | | constexpr std::enable_if_t< |
12587 | | input_range<Rng> && weakly_incrementable<O> && |
12588 | | indirectly_copyable<iterator_t<Rng>, O> && |
12589 | | indirect_unary_predicate<Pred, |
12590 | | projected<iterator_t<Rng>, Proj>>, |
12591 | | remove_copy_if_result<borrowed_iterator_t<Rng>, O>> |
12592 | | operator()(Rng&& rng, O result, Pred pred, Proj proj = Proj{}) const |
12593 | | { |
12594 | | return remove_copy_if_fn::impl(nano::begin(rng), nano::end(rng), |
12595 | | std::move(result), pred, proj); |
12596 | | } |
12597 | | }; |
12598 | | |
12599 | | } // namespace detail |
12600 | | |
12601 | | NANO_INLINE_VAR(detail::remove_copy_if_fn, remove_copy_if) |
12602 | | |
12603 | | NANO_END_NAMESPACE |
12604 | | |
12605 | | #endif |
12606 | | |
12607 | | // nanorange/algorithm/remove_if.hpp |
12608 | | // |
12609 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12610 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12611 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12612 | | |
12613 | | #ifndef NANORANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED |
12614 | | #define NANORANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED |
12615 | | |
12616 | | NANO_BEGIN_NAMESPACE |
12617 | | |
12618 | | namespace detail { |
12619 | | |
12620 | | struct remove_if_fn { |
12621 | | private: |
12622 | | template <typename I, typename S, typename Pred, typename Proj> |
12623 | | static constexpr I impl(I first, S last, Pred& pred, Proj& proj) |
12624 | | { |
12625 | | first = nano::find_if(std::move(first), last, pred, proj); |
12626 | | |
12627 | | if (first == last) { |
12628 | | return first; |
12629 | | } |
12630 | | |
12631 | | for (auto i = next(first); i != last; ++i) { |
12632 | | if (!nano::invoke(pred, nano::invoke(proj, *i))) { |
12633 | | *first = nano::iter_move(i); |
12634 | | ++first; |
12635 | | } |
12636 | | } |
12637 | | |
12638 | | return first; |
12639 | | } |
12640 | | |
12641 | | public: |
12642 | | template <typename I, |
12643 | | typename S, |
12644 | | typename Pred, |
12645 | | typename Proj = identity> |
12646 | | constexpr std::enable_if_t< |
12647 | | forward_iterator<I> && sentinel_for<S, I> && permutable<I> && |
12648 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
12649 | | I> |
12650 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
12651 | | { |
12652 | | return remove_if_fn::impl(std::move(first), std::move(last), pred, |
12653 | | proj); |
12654 | | } |
12655 | | |
12656 | | template <typename Rng, typename Pred, typename Proj = identity> |
12657 | | constexpr std::enable_if_t< |
12658 | | forward_range<Rng> && permutable<iterator_t<Rng>> && |
12659 | | indirect_unary_predicate<Pred, |
12660 | | projected<iterator_t<Rng>, Proj>>, |
12661 | | borrowed_iterator_t<Rng>> |
12662 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
12663 | | { |
12664 | | return remove_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
12665 | | proj); |
12666 | | } |
12667 | | }; |
12668 | | |
12669 | | } // namespace detail |
12670 | | |
12671 | | NANO_INLINE_VAR(detail::remove_if_fn, remove_if) |
12672 | | |
12673 | | NANO_END_NAMESPACE |
12674 | | |
12675 | | #endif |
12676 | | |
12677 | | // nanorange/algorithm/replace.hpp |
12678 | | // |
12679 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12680 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12681 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12682 | | |
12683 | | #ifndef NANORANGE_ALGORITHM_REPLACE_HPP_INCLUDED |
12684 | | #define NANORANGE_ALGORITHM_REPLACE_HPP_INCLUDED |
12685 | | |
12686 | | NANO_BEGIN_NAMESPACE |
12687 | | |
12688 | | namespace detail { |
12689 | | |
12690 | | struct replace_fn { |
12691 | | private: |
12692 | | template <typename I, |
12693 | | typename S, |
12694 | | typename T1, |
12695 | | typename T2, |
12696 | | typename Proj> |
12697 | | static constexpr I impl(I first, |
12698 | | S last, |
12699 | | const T1& old_value, |
12700 | | const T2& new_value, |
12701 | | Proj& proj) |
12702 | | { |
12703 | | while (first != last) { |
12704 | | if (nano::invoke(proj, *first) == old_value) { |
12705 | | *first = new_value; |
12706 | | } |
12707 | | ++first; |
12708 | | } |
12709 | | |
12710 | | return first; |
12711 | | } |
12712 | | |
12713 | | public: |
12714 | | template <typename I, |
12715 | | typename S, |
12716 | | typename T1, |
12717 | | typename T2, |
12718 | | typename Proj = identity> |
12719 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
12720 | | writable<I, const T2&> && |
12721 | | indirect_relation<ranges::equal_to, |
12722 | | projected<I, Proj>, |
12723 | | const T1*>, |
12724 | | I> |
12725 | | operator()(I first, |
12726 | | S last, |
12727 | | const T1& old_value, |
12728 | | const T2& new_value, |
12729 | | Proj proj = Proj{}) const |
12730 | | { |
12731 | | return replace_fn::impl(std::move(first), std::move(last), |
12732 | | old_value, new_value, proj); |
12733 | | } |
12734 | | |
12735 | | template <typename Rng, |
12736 | | typename T1, |
12737 | | typename T2, |
12738 | | typename Proj = identity> |
12739 | | constexpr std::enable_if_t< |
12740 | | input_range<Rng> && writable<iterator_t<Rng>, const T2&> && |
12741 | | indirect_relation<ranges::equal_to, |
12742 | | projected<iterator_t<Rng>, Proj>, |
12743 | | const T1*>, |
12744 | | borrowed_iterator_t<Rng>> |
12745 | | operator()(Rng&& rng, |
12746 | | const T1& old_value, |
12747 | | const T2& new_value, |
12748 | | Proj proj = Proj{}) const |
12749 | | { |
12750 | | return replace_fn::impl(nano::begin(rng), nano::end(rng), old_value, |
12751 | | new_value, proj); |
12752 | | } |
12753 | | }; |
12754 | | |
12755 | | } // namespace detail |
12756 | | |
12757 | | NANO_INLINE_VAR(detail::replace_fn, replace) |
12758 | | |
12759 | | NANO_END_NAMESPACE |
12760 | | |
12761 | | #endif |
12762 | | |
12763 | | // nanorange/algorithm/replace_copy.hpp |
12764 | | // |
12765 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12766 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12767 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12768 | | |
12769 | | #ifndef NANORANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED |
12770 | | #define NANORANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED |
12771 | | |
12772 | | NANO_BEGIN_NAMESPACE |
12773 | | |
12774 | | template <typename I, typename O> |
12775 | | using replace_copy_result = in_out_result<I, O>; |
12776 | | |
12777 | | namespace detail { |
12778 | | |
12779 | | struct replace_copy_fn { |
12780 | | private: |
12781 | | template <typename I, |
12782 | | typename S, |
12783 | | typename O, |
12784 | | typename T1, |
12785 | | typename T2, |
12786 | | typename Proj> |
12787 | | static constexpr replace_copy_result<I, O> impl(I first, |
12788 | | S last, |
12789 | | O result, |
12790 | | const T1& old_value, |
12791 | | const T2& new_value, |
12792 | | Proj& proj) |
12793 | | { |
12794 | | while (first != last) { |
12795 | | if (nano::invoke(proj, *first) == old_value) { |
12796 | | *result = new_value; |
12797 | | } |
12798 | | else { |
12799 | | *result = *first; |
12800 | | } |
12801 | | ++first; |
12802 | | ++result; |
12803 | | } |
12804 | | |
12805 | | return {std::move(first), std::move(result)}; |
12806 | | } |
12807 | | |
12808 | | public: |
12809 | | template <typename I, |
12810 | | typename S, |
12811 | | typename O, |
12812 | | typename T1, |
12813 | | typename T2, |
12814 | | typename Proj = identity> |
12815 | | constexpr std::enable_if_t<input_iterator<I> && sentinel_for<S, I> && |
12816 | | output_iterator<O, const T2&> && |
12817 | | indirectly_copyable<I, O> && |
12818 | | indirect_relation<ranges::equal_to, |
12819 | | projected<I, Proj>, |
12820 | | const T1*>, |
12821 | | replace_copy_result<I, O>> |
12822 | | operator()(I first, |
12823 | | S last, |
12824 | | O result, |
12825 | | const T1& old_value, |
12826 | | const T2& new_value, |
12827 | | Proj proj = Proj{}) const |
12828 | | { |
12829 | | return replace_copy_fn::impl(std::move(first), std::move(last), |
12830 | | std::move(result), old_value, |
12831 | | new_value, proj); |
12832 | | } |
12833 | | |
12834 | | template <typename Rng, |
12835 | | typename O, |
12836 | | typename T1, |
12837 | | typename T2, |
12838 | | typename Proj = identity> |
12839 | | constexpr std::enable_if_t< |
12840 | | input_range<Rng> && output_iterator<O, const T2&> && |
12841 | | indirectly_copyable<iterator_t<Rng>, O> && |
12842 | | indirect_relation<ranges::equal_to, |
12843 | | projected<iterator_t<Rng>, Proj>, |
12844 | | const T1*>, |
12845 | | replace_copy_result<borrowed_iterator_t<Rng>, O>> |
12846 | | operator()(Rng&& rng, |
12847 | | O result, |
12848 | | const T1& old_value, |
12849 | | const T2& new_value, |
12850 | | Proj proj = Proj{}) const |
12851 | | { |
12852 | | return replace_copy_fn::impl(nano::begin(rng), nano::end(rng), |
12853 | | std::move(result), old_value, |
12854 | | new_value, proj); |
12855 | | } |
12856 | | }; |
12857 | | |
12858 | | } // namespace detail |
12859 | | |
12860 | | NANO_INLINE_VAR(detail::replace_copy_fn, replace_copy) |
12861 | | |
12862 | | NANO_END_NAMESPACE |
12863 | | |
12864 | | #endif |
12865 | | |
12866 | | // nanorange/algorithm/replace_copy_if.hpp |
12867 | | // |
12868 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12869 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12870 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12871 | | |
12872 | | #ifndef NANORANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED |
12873 | | #define NANORANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED |
12874 | | |
12875 | | NANO_BEGIN_NAMESPACE |
12876 | | |
12877 | | template <typename I, typename O> |
12878 | | using replace_copy_if_result = in_out_result<I, O>; |
12879 | | |
12880 | | namespace detail { |
12881 | | |
12882 | | struct replace_copy_if_fn { |
12883 | | private: |
12884 | | template <typename I, |
12885 | | typename S, |
12886 | | typename O, |
12887 | | typename Pred, |
12888 | | typename T, |
12889 | | typename Proj> |
12890 | | static constexpr replace_copy_if_result<I, O> impl(I first, |
12891 | | S last, |
12892 | | O result, |
12893 | | Pred& pred, |
12894 | | const T& new_value, |
12895 | | Proj& proj) |
12896 | | { |
12897 | | while (first != last) { |
12898 | | if (nano::invoke(pred, nano::invoke(proj, *first))) { |
12899 | | *result = new_value; |
12900 | | } |
12901 | | else { |
12902 | | *result = *first; |
12903 | | } |
12904 | | ++first; |
12905 | | ++result; |
12906 | | } |
12907 | | |
12908 | | return {std::move(first), std::move(result)}; |
12909 | | } |
12910 | | |
12911 | | public: |
12912 | | template <typename I, |
12913 | | typename S, |
12914 | | typename O, |
12915 | | typename Pred, |
12916 | | typename T, |
12917 | | typename Proj = identity> |
12918 | | constexpr std::enable_if_t< |
12919 | | input_iterator<I> && sentinel_for<S, I> && |
12920 | | output_iterator<O, const T&> && indirectly_copyable<I, O> && |
12921 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
12922 | | replace_copy_if_result<I, O>> |
12923 | | operator()(I first, |
12924 | | S last, |
12925 | | O result, |
12926 | | Pred pred, |
12927 | | const T& new_value, |
12928 | | Proj proj = Proj{}) const |
12929 | | { |
12930 | | return replace_copy_if_fn::impl(std::move(first), std::move(last), |
12931 | | std::move(result), pred, new_value, |
12932 | | proj); |
12933 | | } |
12934 | | |
12935 | | template <typename Rng, |
12936 | | typename O, |
12937 | | typename Pred, |
12938 | | typename T, |
12939 | | typename Proj = identity> |
12940 | | constexpr std::enable_if_t< |
12941 | | input_range<Rng> && output_iterator<O, const T&> && |
12942 | | indirectly_copyable<iterator_t<Rng>, O> && |
12943 | | indirect_unary_predicate<Pred, |
12944 | | projected<iterator_t<Rng>, Proj>>, |
12945 | | replace_copy_if_result<borrowed_iterator_t<Rng>, O>> |
12946 | | operator()(Rng&& rng, |
12947 | | O result, |
12948 | | Pred pred, |
12949 | | const T& new_value, |
12950 | | Proj proj = Proj{}) const |
12951 | | { |
12952 | | return replace_copy_if_fn::impl(nano::begin(rng), nano::end(rng), |
12953 | | std::move(result), pred, new_value, |
12954 | | proj); |
12955 | | } |
12956 | | }; |
12957 | | |
12958 | | } // namespace detail |
12959 | | |
12960 | | NANO_INLINE_VAR(detail::replace_copy_if_fn, replace_copy_if) |
12961 | | |
12962 | | NANO_END_NAMESPACE |
12963 | | |
12964 | | #endif |
12965 | | |
12966 | | // nanorange/algorithm/replace_if.hpp |
12967 | | // |
12968 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
12969 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
12970 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
12971 | | |
12972 | | #ifndef NANORANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED |
12973 | | #define NANORANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED |
12974 | | |
12975 | | NANO_BEGIN_NAMESPACE |
12976 | | |
12977 | | namespace detail { |
12978 | | |
12979 | | struct replace_if_fn { |
12980 | | private: |
12981 | | template <typename I, |
12982 | | typename S, |
12983 | | typename Pred, |
12984 | | typename T, |
12985 | | typename Proj> |
12986 | | static constexpr I impl(I first, |
12987 | | S last, |
12988 | | Pred& pred, |
12989 | | const T& new_value, |
12990 | | Proj& proj) |
12991 | | { |
12992 | | while (first != last) { |
12993 | | if (nano::invoke(pred, nano::invoke(proj, *first))) { |
12994 | | *first = new_value; |
12995 | | } |
12996 | | ++first; |
12997 | | } |
12998 | | |
12999 | | return first; |
13000 | | } |
13001 | | |
13002 | | public: |
13003 | | template <typename I, |
13004 | | typename S, |
13005 | | typename T, |
13006 | | typename Pred, |
13007 | | typename Proj = identity> |
13008 | | constexpr std::enable_if_t< |
13009 | | input_iterator<I> && sentinel_for<S, I> && writable<I, const T&> && |
13010 | | indirect_unary_predicate<Pred, projected<I, Proj>>, |
13011 | | I> |
13012 | | operator()(I first, |
13013 | | S last, |
13014 | | Pred pred, |
13015 | | const T& new_value, |
13016 | | Proj proj = Proj{}) const |
13017 | | { |
13018 | | return replace_if_fn::impl(std::move(first), std::move(last), pred, |
13019 | | new_value, proj); |
13020 | | } |
13021 | | |
13022 | | template <typename Rng, |
13023 | | typename Pred, |
13024 | | typename T2, |
13025 | | typename Proj = identity> |
13026 | | constexpr std::enable_if_t< |
13027 | | input_range<Rng> && writable<iterator_t<Rng>, const T2&> && |
13028 | | indirect_unary_predicate<Pred, |
13029 | | projected<iterator_t<Rng>, Proj>>, |
13030 | | borrowed_iterator_t<Rng>> |
13031 | | operator()(Rng&& rng, |
13032 | | Pred pred, |
13033 | | const T2& new_value, |
13034 | | Proj proj = Proj{}) const |
13035 | | { |
13036 | | return replace_if_fn::impl(nano::begin(rng), nano::end(rng), pred, |
13037 | | new_value, proj); |
13038 | | } |
13039 | | }; |
13040 | | |
13041 | | } // namespace detail |
13042 | | |
13043 | | NANO_INLINE_VAR(detail::replace_if_fn, replace_if) |
13044 | | |
13045 | | NANO_END_NAMESPACE |
13046 | | |
13047 | | #endif |
13048 | | |
13049 | | // nanorange/algorithm/reverse_copy.hpp |
13050 | | // |
13051 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13052 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13053 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13054 | | |
13055 | | #ifndef NANORANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED |
13056 | | #define NANORANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED |
13057 | | |
13058 | | NANO_BEGIN_NAMESPACE |
13059 | | |
13060 | | template <typename I, typename O> |
13061 | | using reverse_copy_result = in_out_result<I, O>; |
13062 | | |
13063 | | namespace detail { |
13064 | | |
13065 | | struct reverse_copy_fn { |
13066 | | private: |
13067 | | template <typename I, typename O> |
13068 | | static constexpr reverse_copy_result<I, O> impl(I first, |
13069 | | I last, |
13070 | | O result) |
13071 | | { |
13072 | | auto ret = last; |
13073 | | while (last != first) { |
13074 | | *result = *--last; |
13075 | | ++result; |
13076 | | } |
13077 | | |
13078 | | return {std::move(ret), std::move(result)}; |
13079 | | } |
13080 | | |
13081 | | template <typename I, typename S, typename O> |
13082 | | static constexpr std::enable_if_t<!same_as<I, S>, |
13083 | | reverse_copy_result<I, O>> |
13084 | | impl(I first, S bound, O result) |
13085 | | { |
13086 | | return reverse_copy_fn::impl( |
13087 | | std::move(first), nano::next(first, bound), std::move(result)); |
13088 | | } |
13089 | | |
13090 | | public: |
13091 | | template <typename I, typename S, typename O> |
13092 | | constexpr std::enable_if_t< |
13093 | | bidirectional_iterator<I> && sentinel_for<S, I> && |
13094 | | weakly_incrementable<O> && indirectly_copyable<I, O>, |
13095 | | reverse_copy_result<I, O>> |
13096 | | operator()(I first, S last, O result) const |
13097 | | { |
13098 | | return reverse_copy_fn::impl(std::move(first), std::move(last), |
13099 | | std::move(result)); |
13100 | | } |
13101 | | |
13102 | | template <typename Rng, typename O> |
13103 | | constexpr std::enable_if_t< |
13104 | | bidirectional_range<Rng> && weakly_incrementable<O> && |
13105 | | indirectly_copyable<iterator_t<Rng>, O>, |
13106 | | reverse_copy_result<borrowed_iterator_t<Rng>, O>> |
13107 | | operator()(Rng&& rng, O result) const |
13108 | | { |
13109 | | return reverse_copy_fn::impl(nano::begin(rng), nano::end(rng), |
13110 | | std::move(result)); |
13111 | | } |
13112 | | }; |
13113 | | |
13114 | | } // namespace detail |
13115 | | |
13116 | | NANO_INLINE_VAR(detail::reverse_copy_fn, reverse_copy) |
13117 | | |
13118 | | NANO_END_NAMESPACE |
13119 | | |
13120 | | #endif |
13121 | | |
13122 | | // nanorange/algorithm/rotate_copy.hpp |
13123 | | // |
13124 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13125 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13126 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13127 | | |
13128 | | #ifndef NANORANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED |
13129 | | #define NANORANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED |
13130 | | |
13131 | | NANO_BEGIN_NAMESPACE |
13132 | | |
13133 | | template <typename I, typename O> |
13134 | | using rotate_copy_result = in_out_result<I, O>; |
13135 | | |
13136 | | namespace detail { |
13137 | | |
13138 | | struct rotate_copy_fn { |
13139 | | private: |
13140 | | template <typename I, typename S, typename O> |
13141 | | static constexpr rotate_copy_result<I, O> impl(I first, |
13142 | | I middle, |
13143 | | S last, |
13144 | | O result) |
13145 | | { |
13146 | | auto ret = nano::copy(middle, std::move(last), std::move(result)); |
13147 | | ret.out = |
13148 | | nano::copy(std::move(first), std::move(middle), ret.out).out; |
13149 | | return ret; |
13150 | | } |
13151 | | |
13152 | | public: |
13153 | | template <typename I, typename S, typename O> |
13154 | | constexpr std::enable_if_t<forward_iterator<I> && sentinel_for<S, I> && |
13155 | | weakly_incrementable<O> && |
13156 | | indirectly_copyable<I, O>, |
13157 | | rotate_copy_result<I, O>> |
13158 | | operator()(I first, I middle, S last, O result) const |
13159 | | { |
13160 | | return rotate_copy_fn::impl(std::move(first), std::move(middle), |
13161 | | std::move(last), std::move(result)); |
13162 | | } |
13163 | | |
13164 | | template <typename Rng, typename O> |
13165 | | constexpr std::enable_if_t< |
13166 | | forward_range<Rng> && weakly_incrementable<O> && |
13167 | | indirectly_copyable<iterator_t<Rng>, O>, |
13168 | | rotate_copy_result<borrowed_iterator_t<Rng>, O>> |
13169 | | operator()(Rng&& rng, iterator_t<Rng> middle, O result) const |
13170 | | { |
13171 | | return rotate_copy_fn::impl(nano::begin(rng), std::move(middle), |
13172 | | nano::end(rng), std::move(result)); |
13173 | | } |
13174 | | }; |
13175 | | |
13176 | | } // namespace detail |
13177 | | |
13178 | | NANO_INLINE_VAR(detail::rotate_copy_fn, rotate_copy) |
13179 | | |
13180 | | NANO_END_NAMESPACE |
13181 | | |
13182 | | #endif |
13183 | | |
13184 | | // nanorange/algorithm/search_n.hpp |
13185 | | // |
13186 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13187 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13188 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13189 | | |
13190 | | #ifndef NANORANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED |
13191 | | #define NANORANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED |
13192 | | |
13193 | | NANO_BEGIN_NAMESPACE |
13194 | | |
13195 | | namespace detail { |
13196 | | |
13197 | | struct search_n_fn { |
13198 | | private: |
13199 | | template <typename I, |
13200 | | typename S, |
13201 | | typename T, |
13202 | | typename Pred, |
13203 | | typename Proj> |
13204 | | static constexpr subrange<I> impl(I first, |
13205 | | S last, |
13206 | | iter_difference_t<I> count, |
13207 | | const T& value, |
13208 | | Pred pred, |
13209 | | Proj& proj) |
13210 | | { |
13211 | | if (count == iter_difference_t<I>{0}) { |
13212 | | return {first, first}; |
13213 | | } |
13214 | | |
13215 | | for (; first != last; ++first) { |
13216 | | if (!nano::invoke(pred, nano::invoke(proj, *first), value)) { |
13217 | | continue; |
13218 | | } |
13219 | | |
13220 | | I save = first; |
13221 | | iter_difference_t<I> running_count{1}; |
13222 | | |
13223 | | while (true) { |
13224 | | if (running_count++ == count) { |
13225 | | // Success |
13226 | | return {save, nano::next(first)}; |
13227 | | } |
13228 | | |
13229 | | if (++first == last) { |
13230 | | // We have run out of elements |
13231 | | return {first, first}; |
13232 | | } |
13233 | | |
13234 | | if (!nano::invoke(pred, nano::invoke(proj, *first), |
13235 | | value)) { |
13236 | | break; |
13237 | | } |
13238 | | } |
13239 | | } |
13240 | | |
13241 | | return {first, first}; |
13242 | | } |
13243 | | |
13244 | | public: |
13245 | | template <typename I, |
13246 | | typename S, |
13247 | | typename T, |
13248 | | typename Pred = ranges::equal_to, |
13249 | | typename Proj = identity> |
13250 | | constexpr auto operator()(I first, |
13251 | | S last, |
13252 | | iter_difference_t<I> count, |
13253 | | const T& value, |
13254 | | Pred pred = Pred{}, |
13255 | | Proj proj = Proj{}) const |
13256 | | -> std::enable_if_t< |
13257 | | forward_iterator<I> && sentinel_for<S, I> && |
13258 | | indirectly_comparable<I, const T*, Pred, Proj>, |
13259 | | subrange<I>> |
13260 | | { |
13261 | | return search_n_fn::impl(std::move(first), std::move(last), count, |
13262 | | value, pred, proj); |
13263 | | } |
13264 | | |
13265 | | template <typename Rng, |
13266 | | typename T, |
13267 | | typename Pred = ranges::equal_to, |
13268 | | typename Proj = identity> |
13269 | | constexpr auto operator()(Rng&& rng, |
13270 | | iter_difference_t<iterator_t<Rng>> count, |
13271 | | const T& value, |
13272 | | Pred pred = Pred{}, |
13273 | | Proj proj = Proj{}) const |
13274 | | -> std::enable_if_t<forward_range<Rng> && |
13275 | | indirectly_comparable<iterator_t<Rng>, |
13276 | | const T*, |
13277 | | Pred, |
13278 | | Proj>, |
13279 | | borrowed_subrange_t<Rng>> |
13280 | | { |
13281 | | return search_n_fn::impl(nano::begin(rng), nano::end(rng), count, |
13282 | | value, pred, proj); |
13283 | | } |
13284 | | }; |
13285 | | |
13286 | | } // namespace detail |
13287 | | |
13288 | | NANO_INLINE_VAR(detail::search_n_fn, search_n) |
13289 | | |
13290 | | NANO_END_NAMESPACE |
13291 | | |
13292 | | #endif |
13293 | | |
13294 | | // nanorange/algorithm/set_difference.hpp |
13295 | | // |
13296 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13297 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13298 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13299 | | |
13300 | | #ifndef NANORANGE_ALGORITHM_SET_DIFFERENCE_HPP_INCLUDED |
13301 | | #define NANORANGE_ALGORITHM_SET_DIFFERENCE_HPP_INCLUDED |
13302 | | |
13303 | | NANO_BEGIN_NAMESPACE |
13304 | | |
13305 | | template <typename I, typename O> |
13306 | | using set_difference_result = in_out_result<I, O>; |
13307 | | |
13308 | | namespace detail { |
13309 | | |
13310 | | struct set_difference_fn { |
13311 | | private: |
13312 | | template <typename I1, |
13313 | | typename S1, |
13314 | | typename I2, |
13315 | | typename S2, |
13316 | | typename O, |
13317 | | typename Comp, |
13318 | | typename Proj1, |
13319 | | typename Proj2> |
13320 | | static constexpr set_difference_result<I1, O> impl(I1 first1, |
13321 | | S1 last1, |
13322 | | I2 first2, |
13323 | | S2 last2, |
13324 | | O result, |
13325 | | Comp& comp, |
13326 | | Proj1& proj1, |
13327 | | Proj2& proj2) |
13328 | | { |
13329 | | while (first1 != last1) { |
13330 | | if (first2 == last2) { |
13331 | | // We've reached the end of range2, so copy all the |
13332 | | // remaining elements from range1 and exit |
13333 | | auto res = nano::copy(std::move(first1), std::move(last1), |
13334 | | std::move(result)); |
13335 | | first1 = std::move(res.in); |
13336 | | result = std::move(res.out); |
13337 | | |
13338 | | break; |
13339 | | } |
13340 | | |
13341 | | // If the element from r1 compares less than the one from r2, |
13342 | | // then copy it |
13343 | | if (nano::invoke(comp, nano::invoke(proj1, *first1), |
13344 | | nano::invoke(proj2, *first2))) { |
13345 | | *result = *first1; |
13346 | | ++first1; |
13347 | | ++result; |
13348 | | } |
13349 | | else { |
13350 | | // We now know that !(r1 < r2). If !(r2 < r1) as well, then |
13351 | | // elements are equal and we can skip |
13352 | | if (!nano::invoke(comp, nano::invoke(proj2, *first2), |
13353 | | nano::invoke(proj1, *first1))) { |
13354 | | ++first1; |
13355 | | } |
13356 | | ++first2; |
13357 | | } |
13358 | | } |
13359 | | |
13360 | | return {std::move(first1), std::move(result)}; |
13361 | | } |
13362 | | |
13363 | | public: |
13364 | | template <typename I1, |
13365 | | typename S1, |
13366 | | typename I2, |
13367 | | typename S2, |
13368 | | typename O, |
13369 | | typename Comp = ranges::less, |
13370 | | typename Proj1 = identity, |
13371 | | typename Proj2 = identity> |
13372 | | constexpr std::enable_if_t< |
13373 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
13374 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
13375 | | mergeable<I1, I2, O, Comp, Proj1, Proj2>, |
13376 | | set_difference_result<I1, O>> |
13377 | | operator()(I1 first1, |
13378 | | S1 last1, |
13379 | | I2 first2, |
13380 | | S2 last2, |
13381 | | O result, |
13382 | | Comp comp = Comp{}, |
13383 | | Proj1 proj1 = Proj1{}, |
13384 | | Proj2 proj2 = Proj2{}) const |
13385 | | { |
13386 | | return set_difference_fn::impl( |
13387 | | std::move(first1), std::move(last1), std::move(first2), |
13388 | | std::move(last2), std::move(result), comp, proj1, proj2); |
13389 | | } |
13390 | | |
13391 | | template <typename Rng1, |
13392 | | typename Rng2, |
13393 | | typename O, |
13394 | | typename Comp = ranges::less, |
13395 | | typename Proj1 = identity, |
13396 | | typename Proj2 = identity> |
13397 | | constexpr std::enable_if_t< |
13398 | | input_range<Rng1> && input_range<Rng2> && weakly_incrementable<O> && |
13399 | | mergeable<iterator_t<Rng1>, |
13400 | | iterator_t<Rng2>, |
13401 | | O, |
13402 | | Comp, |
13403 | | Proj1, |
13404 | | Proj2>, |
13405 | | set_difference_result<borrowed_iterator_t<Rng1>, O>> |
13406 | | operator()(Rng1&& rng1, |
13407 | | Rng2&& rng2, |
13408 | | O result, |
13409 | | Comp comp = Comp{}, |
13410 | | Proj1 proj1 = Proj1{}, |
13411 | | Proj2 proj2 = Proj2{}) const |
13412 | | { |
13413 | | return set_difference_fn::impl( |
13414 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), |
13415 | | nano::end(rng2), std::move(result), comp, proj1, proj2); |
13416 | | } |
13417 | | }; |
13418 | | |
13419 | | } // namespace detail |
13420 | | |
13421 | | NANO_INLINE_VAR(detail::set_difference_fn, set_difference) |
13422 | | |
13423 | | NANO_END_NAMESPACE |
13424 | | |
13425 | | #endif |
13426 | | |
13427 | | // nanorange/algorithm/set_intersection.hpp |
13428 | | // |
13429 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13430 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13431 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13432 | | |
13433 | | #ifndef NANORANGE_ALGORITHM_SET_INTERSECTION_HPP_INCLUDED |
13434 | | #define NANORANGE_ALGORITHM_SET_INTERSECTION_HPP_INCLUDED |
13435 | | |
13436 | | NANO_BEGIN_NAMESPACE |
13437 | | |
13438 | | namespace detail { |
13439 | | |
13440 | | struct set_intersection_fn { |
13441 | | private: |
13442 | | template <typename I1, |
13443 | | typename S1, |
13444 | | typename I2, |
13445 | | typename S2, |
13446 | | typename O, |
13447 | | typename Comp, |
13448 | | typename Proj1, |
13449 | | typename Proj2> |
13450 | | static constexpr O impl(I1 first1, |
13451 | | S1 last1, |
13452 | | I2 first2, |
13453 | | S2 last2, |
13454 | | O result, |
13455 | | Comp& comp, |
13456 | | Proj1& proj1, |
13457 | | Proj2& proj2) |
13458 | | { |
13459 | | while (first1 != last1 && first2 != last2) { |
13460 | | if (nano::invoke(comp, nano::invoke(proj1, *first1), |
13461 | | nano::invoke(proj2, *first2))) { |
13462 | | ++first1; |
13463 | | } |
13464 | | else { |
13465 | | if (!nano::invoke(comp, nano::invoke(proj2, *first2), |
13466 | | nano::invoke(proj1, *first1))) { |
13467 | | *result = *first1; |
13468 | | ++result; |
13469 | | ++first1; |
13470 | | } |
13471 | | ++first2; |
13472 | | } |
13473 | | } |
13474 | | |
13475 | | return result; |
13476 | | } |
13477 | | |
13478 | | public: |
13479 | | template <typename I1, |
13480 | | typename S1, |
13481 | | typename I2, |
13482 | | typename S2, |
13483 | | typename O, |
13484 | | typename Comp = ranges::less, |
13485 | | typename Proj1 = identity, |
13486 | | typename Proj2 = identity> |
13487 | | constexpr std::enable_if_t< |
13488 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
13489 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
13490 | | mergeable<I1, I2, O, Comp, Proj1, Proj2>, |
13491 | | O> |
13492 | | operator()(I1 first1, |
13493 | | S1 last1, |
13494 | | I2 first2, |
13495 | | S2 last2, |
13496 | | O result, |
13497 | | Comp comp = Comp{}, |
13498 | | Proj1 proj1 = Proj1{}, |
13499 | | Proj2 proj2 = Proj2{}) const |
13500 | | { |
13501 | | return set_intersection_fn::impl( |
13502 | | std::move(first1), std::move(last1), std::move(first2), |
13503 | | std::move(last2), std::move(result), comp, proj1, proj2); |
13504 | | } |
13505 | | |
13506 | | template <typename Rng1, |
13507 | | typename Rng2, |
13508 | | typename O, |
13509 | | typename Comp = ranges::less, |
13510 | | typename Proj1 = identity, |
13511 | | typename Proj2 = identity> |
13512 | | constexpr std::enable_if_t<input_range<Rng1> && input_range<Rng2> && |
13513 | | weakly_incrementable<O> && |
13514 | | mergeable<iterator_t<Rng1>, |
13515 | | iterator_t<Rng2>, |
13516 | | O, |
13517 | | Comp, |
13518 | | Proj1, |
13519 | | Proj2>, |
13520 | | O> |
13521 | | operator()(Rng1&& rng1, |
13522 | | Rng2&& rng2, |
13523 | | O result, |
13524 | | Comp comp = Comp{}, |
13525 | | Proj1 proj1 = Proj1{}, |
13526 | | Proj2 proj2 = Proj2{}) const |
13527 | | { |
13528 | | return set_intersection_fn::impl( |
13529 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), |
13530 | | nano::end(rng2), std::move(result), comp, proj1, proj2); |
13531 | | } |
13532 | | }; |
13533 | | |
13534 | | } // namespace detail |
13535 | | |
13536 | | NANO_INLINE_VAR(detail::set_intersection_fn, set_intersection) |
13537 | | |
13538 | | NANO_END_NAMESPACE |
13539 | | |
13540 | | #endif |
13541 | | |
13542 | | // nanorange/algorithm/set_symmetric_difference.hpp |
13543 | | // |
13544 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13545 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13546 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13547 | | |
13548 | | #ifndef NANORANGE_ALGORITHM_SET_SYMMETRIC_DIFFERENCE_HPP_INCLUDED |
13549 | | #define NANORANGE_ALGORITHM_SET_SYMMETRIC_DIFFERENCE_HPP_INCLUDED |
13550 | | |
13551 | | NANO_BEGIN_NAMESPACE |
13552 | | |
13553 | | template <typename I1, typename I2, typename O> |
13554 | | using set_symmetric_difference_result = in_in_out_result<I1, I2, O>; |
13555 | | |
13556 | | namespace detail { |
13557 | | |
13558 | | struct set_symmetric_difference_fn { |
13559 | | private: |
13560 | | template <typename I1, |
13561 | | typename S1, |
13562 | | typename I2, |
13563 | | typename S2, |
13564 | | typename O, |
13565 | | typename Comp, |
13566 | | typename Proj1, |
13567 | | typename Proj2> |
13568 | | static constexpr set_symmetric_difference_result<I1, I2, O> impl( |
13569 | | I1 first1, |
13570 | | S1 last1, |
13571 | | I2 first2, |
13572 | | S2 last2, |
13573 | | O result, |
13574 | | Comp& comp, |
13575 | | Proj1& proj1, |
13576 | | Proj2& proj2) |
13577 | | { |
13578 | | while (true) { |
13579 | | if (first1 == last1) { |
13580 | | auto copy_res = nano::copy( |
13581 | | std::move(first2), std::move(last2), std::move(result)); |
13582 | | |
13583 | | return {std::move(first1), std::move(copy_res.in), |
13584 | | std::move(copy_res.out)}; |
13585 | | } |
13586 | | |
13587 | | if (first2 == last2) { |
13588 | | auto copy_res = nano::copy( |
13589 | | std::move(first1), std::move(last1), std::move(result)); |
13590 | | return {std::move(copy_res.in), std::move(first2), |
13591 | | std::move(copy_res.out)}; |
13592 | | } |
13593 | | |
13594 | | // If r1 is less than r2, copy it to the output |
13595 | | if (nano::invoke(comp, nano::invoke(proj1, *first1), |
13596 | | nano::invoke(proj2, *first2))) { |
13597 | | *result = *first1; |
13598 | | ++result; |
13599 | | ++first1; |
13600 | | } |
13601 | | else { |
13602 | | // We now know that !(r1 < r2). If !(r2 < r1) as well then |
13603 | | // the elements are equal -- so skip |
13604 | | if (!nano::invoke(comp, nano::invoke(proj2, *first2), |
13605 | | nano::invoke(proj1, *first1))) { |
13606 | | ++first1; |
13607 | | } |
13608 | | else { |
13609 | | // Otherwise copy first2 |
13610 | | *result = *first2; |
13611 | | ++result; |
13612 | | } |
13613 | | ++first2; |
13614 | | } |
13615 | | } |
13616 | | } |
13617 | | |
13618 | | public: |
13619 | | template <typename I1, |
13620 | | typename S1, |
13621 | | typename I2, |
13622 | | typename S2, |
13623 | | typename O, |
13624 | | typename Comp = ranges::less, |
13625 | | typename Proj1 = identity, |
13626 | | typename Proj2 = identity> |
13627 | | constexpr std::enable_if_t< |
13628 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
13629 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
13630 | | mergeable<I1, I2, O, Comp, Proj1, Proj2>, |
13631 | | set_symmetric_difference_result<I1, I2, O>> |
13632 | | operator()(I1 first1, |
13633 | | S1 last1, |
13634 | | I2 first2, |
13635 | | S2 last2, |
13636 | | O result, |
13637 | | Comp comp = Comp{}, |
13638 | | Proj1 proj1 = Proj1{}, |
13639 | | Proj2 proj2 = Proj2{}) const |
13640 | | { |
13641 | | return set_symmetric_difference_fn::impl( |
13642 | | std::move(first1), std::move(last1), std::move(first2), |
13643 | | std::move(last2), std::move(result), comp, proj1, proj2); |
13644 | | } |
13645 | | |
13646 | | template <typename Rng1, |
13647 | | typename Rng2, |
13648 | | typename O, |
13649 | | typename Comp = ranges::less, |
13650 | | typename Proj1 = identity, |
13651 | | typename Proj2 = identity> |
13652 | | std::enable_if_t< |
13653 | | input_range<Rng1> && input_range<Rng2> && weakly_incrementable<O> && |
13654 | | mergeable<iterator_t<Rng1>, |
13655 | | iterator_t<Rng2>, |
13656 | | O, |
13657 | | Comp, |
13658 | | Proj1, |
13659 | | Proj2>, |
13660 | | set_symmetric_difference_result<borrowed_iterator_t<Rng1>, |
13661 | | borrowed_iterator_t<Rng2>, |
13662 | | O>> |
13663 | | operator()(Rng1&& rng1, |
13664 | | Rng2&& rng2, |
13665 | | O result, |
13666 | | Comp comp = Comp{}, |
13667 | | Proj1 proj1 = Proj1{}, |
13668 | | Proj2 proj2 = Proj2{}) const |
13669 | | { |
13670 | | return set_symmetric_difference_fn::impl( |
13671 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), |
13672 | | nano::end(rng2), std::move(result), comp, proj1, proj2); |
13673 | | } |
13674 | | }; |
13675 | | |
13676 | | } // namespace detail |
13677 | | |
13678 | | NANO_INLINE_VAR(detail::set_symmetric_difference_fn, set_symmetric_difference) |
13679 | | |
13680 | | NANO_END_NAMESPACE |
13681 | | |
13682 | | #endif |
13683 | | |
13684 | | // nanorange/algorithm/set_union.hpp |
13685 | | // |
13686 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13687 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13688 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13689 | | |
13690 | | #ifndef NANORANGE_ALGORITHM_SET_UNION_HPP_INCLUDED |
13691 | | #define NANORANGE_ALGORITHM_SET_UNION_HPP_INCLUDED |
13692 | | |
13693 | | NANO_BEGIN_NAMESPACE |
13694 | | |
13695 | | template <typename I1, typename I2, typename O> |
13696 | | using set_union_result = in_in_out_result<I1, I2, O>; |
13697 | | |
13698 | | namespace detail { |
13699 | | |
13700 | | struct set_union_fn { |
13701 | | private: |
13702 | | template <typename I1, |
13703 | | typename S1, |
13704 | | typename I2, |
13705 | | typename S2, |
13706 | | typename O, |
13707 | | typename Comp, |
13708 | | typename Proj1, |
13709 | | typename Proj2> |
13710 | | static constexpr set_union_result<I1, I2, O> impl(I1 first1, |
13711 | | S1 last1, |
13712 | | I2 first2, |
13713 | | S2 last2, |
13714 | | O result, |
13715 | | Comp& comp, |
13716 | | Proj1& proj1, |
13717 | | Proj2& proj2) |
13718 | | { |
13719 | | while (first1 != last1) { |
13720 | | // If we've reached the end of the second range, copy any |
13721 | | // remaining elements from the first range and quit |
13722 | | if (first2 == last2) { |
13723 | | auto copy_res = nano::copy( |
13724 | | std::move(first1), std::move(last1), std::move(result)); |
13725 | | |
13726 | | first1 = std::move(copy_res.in); |
13727 | | result = std::move(copy_res.out); |
13728 | | |
13729 | | break; |
13730 | | } |
13731 | | |
13732 | | // If this element from r1 is less than the current element from |
13733 | | // r2, copy it and move on |
13734 | | if (nano::invoke(comp, nano::invoke(proj1, *first1), |
13735 | | nano::invoke(proj2, *first2))) { |
13736 | | *result = *first1; |
13737 | | ++first1; |
13738 | | } |
13739 | | else { |
13740 | | // Now, we know that !(r1 < r2). If we also have !(r2 < r1) |
13741 | | // then the elements compare equal, so skip it |
13742 | | if (!nano::invoke(comp, nano::invoke(proj2, *first2), |
13743 | | nano::invoke(proj1, *first1))) { |
13744 | | ++first1; |
13745 | | } |
13746 | | *result = *first2; |
13747 | | ++first2; |
13748 | | } |
13749 | | ++result; |
13750 | | } |
13751 | | |
13752 | | // We've run out of elements of range1, so copy all the remaining |
13753 | | // elements of range2 |
13754 | | auto copy_res = nano::copy(std::move(first2), std::move(last2), |
13755 | | std::move(result)); |
13756 | | |
13757 | | return {std::move(first1), std::move(copy_res.in), |
13758 | | std::move(copy_res.out)}; |
13759 | | } |
13760 | | |
13761 | | public: |
13762 | | template <typename I1, |
13763 | | typename S1, |
13764 | | typename I2, |
13765 | | typename S2, |
13766 | | typename O, |
13767 | | typename Comp = ranges::less, |
13768 | | typename Proj1 = identity, |
13769 | | typename Proj2 = identity> |
13770 | | constexpr std::enable_if_t< |
13771 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
13772 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
13773 | | mergeable<I1, I2, O, Comp, Proj1, Proj2>, |
13774 | | set_union_result<I1, I2, O>> |
13775 | | operator()(I1 first1, |
13776 | | S1 last1, |
13777 | | I2 first2, |
13778 | | S2 last2, |
13779 | | O result, |
13780 | | Comp comp = Comp{}, |
13781 | | Proj1 proj1 = Proj1{}, |
13782 | | Proj2 proj2 = Proj2{}) const |
13783 | | { |
13784 | | return set_union_fn::impl(std::move(first1), std::move(last1), |
13785 | | std::move(first2), std::move(last2), |
13786 | | std::move(result), comp, proj1, proj2); |
13787 | | } |
13788 | | |
13789 | | template <typename Rng1, |
13790 | | typename Rng2, |
13791 | | typename O, |
13792 | | typename Comp = ranges::less, |
13793 | | typename Proj1 = identity, |
13794 | | typename Proj2 = identity> |
13795 | | constexpr std::enable_if_t<input_range<Rng1> && input_range<Rng2> && |
13796 | | weakly_incrementable<O> && |
13797 | | mergeable<iterator_t<Rng1>, |
13798 | | iterator_t<Rng2>, |
13799 | | O, |
13800 | | Comp, |
13801 | | Proj1, |
13802 | | Proj2>, |
13803 | | set_union_result<borrowed_iterator_t<Rng1>, |
13804 | | borrowed_iterator_t<Rng2>, |
13805 | | O>> |
13806 | | operator()(Rng1&& rng1, |
13807 | | Rng2&& rng2, |
13808 | | O result, |
13809 | | Comp comp = Comp{}, |
13810 | | Proj1 proj1 = Proj1{}, |
13811 | | Proj2 proj2 = Proj2{}) const |
13812 | | { |
13813 | | return set_union_fn::impl(nano::begin(rng1), nano::end(rng1), |
13814 | | nano::begin(rng2), nano::end(rng2), |
13815 | | std::move(result), comp, proj1, proj2); |
13816 | | } |
13817 | | }; |
13818 | | |
13819 | | } // namespace detail |
13820 | | |
13821 | | NANO_INLINE_VAR(detail::set_union_fn, set_union) |
13822 | | |
13823 | | NANO_END_NAMESPACE |
13824 | | |
13825 | | #endif |
13826 | | |
13827 | | // nanorange/algorithm/sample.hpp |
13828 | | // |
13829 | | //===----------------------------------------------------------------------===// |
13830 | | // |
13831 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
13832 | | // See https://llvm.org/LICENSE.txt for license information. |
13833 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
13834 | | // |
13835 | | //===----------------------------------------------------------------------===// |
13836 | | |
13837 | | #ifndef NANORANGE_ALGORITHM_SAMPLE_HPP_INCLUDED |
13838 | | #define NANORANGE_ALGORITHM_SAMPLE_HPP_INCLUDED |
13839 | | |
13840 | | // nanorange/random.hpp |
13841 | | // |
13842 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13843 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13844 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13845 | | |
13846 | | #ifndef NANORANGE_RANDOM_HPP_INCLUDED |
13847 | | #define NANORANGE_RANDOM_HPP_INCLUDED |
13848 | | |
13849 | | // nanorange/concepts.hpp |
13850 | | // |
13851 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
13852 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
13853 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
13854 | | |
13855 | | #ifndef NANORANGE_CONCEPTS_HPP_INCLUDED |
13856 | | #define NANORANGE_CONCEPTS_HPP_INCLUDED |
13857 | | |
13858 | | #endif |
13859 | | |
13860 | | NANO_BEGIN_NAMESPACE |
13861 | | |
13862 | | // [rand.req.urng] |
13863 | | |
13864 | | namespace detail { |
13865 | | |
13866 | | struct uniform_random_bit_generator_concept { |
13867 | | template <typename> |
13868 | | static auto test(long) -> std::false_type; |
13869 | | |
13870 | | template <typename G> |
13871 | | static auto test(int) -> std::enable_if_t< |
13872 | | invocable<G&> && unsigned_integral<invoke_result_t<G&>> && |
13873 | | detail::requires_<uniform_random_bit_generator_concept, G>, |
13874 | | std::true_type>; |
13875 | | |
13876 | | template <typename G> |
13877 | | auto requires_() |
13878 | | -> decltype(requires_expr< |
13879 | | same_as<decltype(G::min()), invoke_result_t<G&>>>{}, |
13880 | | requires_expr<same_as<decltype(G::max()), |
13881 | | invoke_result_t<G&>>>{}); |
13882 | | }; |
13883 | | |
13884 | | } // namespace detail |
13885 | | |
13886 | | template <typename G> |
13887 | | NANO_CONCEPT uniform_random_bit_generator = |
13888 | | decltype(detail::uniform_random_bit_generator_concept::test<G>(0))::value; |
13889 | | |
13890 | | NANO_END_NAMESPACE |
13891 | | |
13892 | | #endif |
13893 | | |
13894 | | #include <random> |
13895 | | |
13896 | | NANO_BEGIN_NAMESPACE |
13897 | | |
13898 | | namespace detail { |
13899 | | |
13900 | | struct sample_fn { |
13901 | | private: |
13902 | | template <typename I, typename S, typename O, typename Gen> |
13903 | | static O impl_fwd(I first, |
13904 | | S last, |
13905 | | O out, |
13906 | | iter_difference_t<I> n, |
13907 | | Gen& g) |
13908 | | { |
13909 | | using diff_t = iter_difference_t<I>; |
13910 | | using distr_t = std::uniform_int_distribution<diff_t>; |
13911 | | using param_t = typename distr_t::param_type; |
13912 | | |
13913 | | distr_t D; |
13914 | | |
13915 | | auto unsampled_size = nano::distance(first, last); |
13916 | | |
13917 | | for (n = nano::min(n, unsampled_size); n != 0; ++first) { |
13918 | | if (D(g, param_t(0, --unsampled_size)) < n) { |
13919 | | *out++ = *first; |
13920 | | --n; |
13921 | | } |
13922 | | } |
13923 | | |
13924 | | return out; |
13925 | | } |
13926 | | template <typename I, typename S, typename O, typename Gen> |
13927 | | static O impl_ra(I first, S last, O out, iter_difference_t<I> n, Gen& g) |
13928 | | { |
13929 | | using diff_t = iter_difference_t<I>; |
13930 | | using distr_t = std::uniform_int_distribution<diff_t>; |
13931 | | using param_t = typename distr_t::param_type; |
13932 | | |
13933 | | distr_t D; |
13934 | | diff_t k = 0; |
13935 | | |
13936 | | for (; first != last && k < n; ++first, (void)++k) { |
13937 | | out[k] = *first; |
13938 | | } |
13939 | | |
13940 | | diff_t size = k; |
13941 | | for (; first != last; ++first, (void)++k) { |
13942 | | diff_t r = distr_t(0, k)(g); |
13943 | | if (D(g, param_t(0, k)) < size) { |
13944 | | out[r] = *first; |
13945 | | } |
13946 | | } |
13947 | | |
13948 | | return out + nano::min(n, k); |
13949 | | } |
13950 | | |
13951 | | template <typename I, typename S, typename O, typename Gen> |
13952 | | static O impl(I first, S last, O out, iter_difference_t<I> n, Gen& g) |
13953 | | { |
13954 | | if constexpr (nano::forward_iterator<I>) { |
13955 | | return impl_fwd(std::move(first), std::move(last), |
13956 | | std::move(out), n, g); |
13957 | | } |
13958 | | else { |
13959 | | return impl_ra(std::move(first), std::move(last), |
13960 | | std::move(out), n, g); |
13961 | | } |
13962 | | } |
13963 | | |
13964 | | public: |
13965 | | template <typename I, typename S, typename O, typename Gen> |
13966 | | std::enable_if_t< |
13967 | | input_iterator<I> && sentinel_for<S, I> && |
13968 | | weakly_incrementable<O> && |
13969 | | (forward_iterator<I> || |
13970 | | random_access_iterator<O>)&&indirectly_copyable<I, O> && |
13971 | | uniform_random_bit_generator<std::remove_reference_t<Gen>>, |
13972 | | O> |
13973 | | operator()(I first, S last, O out, iter_difference_t<I> n, Gen&& gen) |
13974 | | const |
13975 | | { |
13976 | | return sample_fn::impl(std::move(first), std::move(last), |
13977 | | std::move(out), std::move(n), |
13978 | | std::forward<Gen>(gen)); |
13979 | | } |
13980 | | |
13981 | | template <typename Rng, typename O, typename Gen> |
13982 | | std::enable_if_t< |
13983 | | input_range<Rng> && weakly_incrementable<O> && |
13984 | | (forward_range<Rng> || |
13985 | | random_access_iterator< |
13986 | | O>)&&indirectly_copyable<iterator_t<Rng>, O> && |
13987 | | uniform_random_bit_generator<std::remove_reference_t<Gen>>, |
13988 | | O> |
13989 | | operator()(Rng&& rng, O out, range_difference_t<Rng> n, Gen&& gen) const |
13990 | | { |
13991 | | return sample_fn::impl(nano::begin(rng), nano::end(rng), |
13992 | | std::move(out), std::move(n), |
13993 | | std::forward<Gen>(gen)); |
13994 | | } |
13995 | | }; |
13996 | | |
13997 | | } // namespace detail |
13998 | | |
13999 | | NANO_INLINE_VAR(detail::sample_fn, sample) |
14000 | | |
14001 | | NANO_END_NAMESPACE |
14002 | | |
14003 | | #endif |
14004 | | |
14005 | | // nanorange/algorithm/shuffle.hpp |
14006 | | // |
14007 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
14008 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
14009 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
14010 | | |
14011 | | #ifndef NANORANGE_ALGORITHM_SHUFFLE_HPP_INCLUDED |
14012 | | #define NANORANGE_ALGORITHM_SHUFFLE_HPP_INCLUDED |
14013 | | |
14014 | | #include <random> |
14015 | | |
14016 | | NANO_BEGIN_NAMESPACE |
14017 | | |
14018 | | namespace detail { |
14019 | | |
14020 | | struct shuffle_fn { |
14021 | | private: |
14022 | | template <typename I, typename S, typename Gen> |
14023 | | static constexpr I impl(I first, S last, Gen&& g) |
14024 | | { |
14025 | | using diff_t = iter_difference_t<I>; |
14026 | | using distr_t = std::uniform_int_distribution<diff_t>; |
14027 | | using param_t = typename distr_t::param_type; |
14028 | | |
14029 | | distr_t D; |
14030 | | const auto n = last - first; // OK, we have SizedSentinel |
14031 | | |
14032 | | for (diff_t i = 0; i < n; i++) { |
14033 | | nano::iter_swap(first + i, first + D(g, param_t(0, i))); |
14034 | | } |
14035 | | |
14036 | | return next(first, last); |
14037 | | } |
14038 | | |
14039 | | public: |
14040 | | template <typename I, typename S, typename Gen> |
14041 | | constexpr std::enable_if_t< |
14042 | | random_access_iterator<I> && sentinel_for<S, I> && |
14043 | | uniform_random_bit_generator<std::remove_reference_t<Gen>> && |
14044 | | convertible_to<invoke_result_t<Gen&>, iter_difference_t<I>>, |
14045 | | I> |
14046 | | operator()(I first, S last, Gen&& gen) const |
14047 | | { |
14048 | | return shuffle_fn::impl(std::move(first), std::move(last), |
14049 | | std::forward<Gen>(gen)); |
14050 | | } |
14051 | | |
14052 | | template <typename Rng, typename Gen> |
14053 | | constexpr std::enable_if_t< |
14054 | | random_access_range<Rng> && |
14055 | | uniform_random_bit_generator<std::remove_reference_t<Gen>> && |
14056 | | convertible_to<invoke_result_t<Gen&>, |
14057 | | iter_difference_t<iterator_t<Rng>>>, |
14058 | | borrowed_iterator_t<Rng>> |
14059 | | operator()(Rng&& rng, Gen&& gen) const |
14060 | | { |
14061 | | return shuffle_fn::impl(nano::begin(rng), nano::end(rng), |
14062 | | std::forward<Gen>(gen)); |
14063 | | } |
14064 | | }; |
14065 | | |
14066 | | } // namespace detail |
14067 | | |
14068 | | NANO_INLINE_VAR(detail::shuffle_fn, shuffle) |
14069 | | |
14070 | | NANO_END_NAMESPACE |
14071 | | |
14072 | | #endif |
14073 | | |
14074 | | // nanorange/algorithm/sort.hpp |
14075 | | // |
14076 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
14077 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
14078 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
14079 | | |
14080 | | #ifndef NANORANGE_ALGORITHM_SORT_HPP_INCLUDED |
14081 | | #define NANORANGE_ALGORITHM_SORT_HPP_INCLUDED |
14082 | | |
14083 | | // nanorange/detail/algorithm/pqdsort.hpp |
14084 | | // |
14085 | | // Copyright Orson Peters 2017. |
14086 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
14087 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
14088 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
14089 | | |
14090 | | // Modified from Boost.Sort by Orson Peters |
14091 | | // https://github.com/boostorg/sort/blob/develop/include/boost/sort/pdqsort/pdqsort.hpp |
14092 | | |
14093 | | #ifndef NANORANGE_DETAIL_ALGORITHM_PDQSORT_HPP_INCLUDED |
14094 | | #define NANORANGE_DETAIL_ALGORITHM_PDQSORT_HPP_INCLUDED |
14095 | | |
14096 | | NANO_BEGIN_NAMESPACE |
14097 | | |
14098 | | namespace detail { |
14099 | | |
14100 | | // Partitions below this size are sorted using insertion sort. |
14101 | | constexpr int pdqsort_insertion_sort_threshold = 24; |
14102 | | |
14103 | | // Partitions above this size use Tukey's ninther to select the pivot. |
14104 | | constexpr int pdqsort_ninther_threshold = 128; |
14105 | | |
14106 | | // When we detect an already sorted partition, attempt an insertion sort |
14107 | | // that allows this amount of element moves before giving up. |
14108 | | constexpr int pqdsort_partial_insertion_sort_limit = 8; |
14109 | | |
14110 | | // Must be multiple of 8 due to loop unrolling, and < 256 to fit in unsigned |
14111 | | // char. |
14112 | | constexpr int pdqsort_block_size = 64; |
14113 | | |
14114 | | // Cacheline size, assumes power of two. |
14115 | | constexpr int pdqsort_cacheline_size = 64; |
14116 | | |
14117 | | template <typename> |
14118 | | struct is_default_compare : std::false_type {}; |
14119 | | template <> |
14120 | | struct is_default_compare<nano::less> : std::true_type {}; |
14121 | | template <> |
14122 | | struct is_default_compare<nano::greater> : std::true_type {}; |
14123 | | template <typename T> |
14124 | | struct is_default_compare<std::less<T>> : std::true_type {}; |
14125 | | template <typename T> |
14126 | | struct is_default_compare<std::greater<T>> : std::true_type {}; |
14127 | | |
14128 | | template <typename T> |
14129 | | constexpr bool is_default_compare_v = is_default_compare<T>::value; |
14130 | | |
14131 | | // Returns floor(log2(n)), assumes n > 0. |
14132 | | template <class T> |
14133 | | constexpr int log2(T n) |
14134 | 6.99k | { |
14135 | 6.99k | int log = 0; |
14136 | 26.4k | while (n >>= 1) |
14137 | 19.4k | ++log; |
14138 | 6.99k | return log; |
14139 | 6.99k | } |
14140 | | |
14141 | | // Sorts [begin, end) using insertion sort with the given comparison |
14142 | | // function. |
14143 | | template <typename I, typename Comp, typename Proj> |
14144 | | constexpr void insertion_sort(I begin, I end, Comp& comp, Proj& proj) |
14145 | 6.72k | { |
14146 | 6.72k | using T = iter_value_t<I>; |
14147 | | |
14148 | 6.72k | if (begin == end) { |
14149 | 1.49k | return; |
14150 | 1.49k | } |
14151 | | |
14152 | 25.2k | for (I cur = begin + 1; cur != end; ++cur) { |
14153 | 20.0k | I sift = cur; |
14154 | 20.0k | I sift_1 = cur - 1; |
14155 | | |
14156 | | // Compare first so we can avoid 2 moves for an element already |
14157 | | // positioned correctly. |
14158 | 20.0k | if (nano::invoke(comp, nano::invoke(proj, *sift), |
14159 | 20.0k | nano::invoke(proj, *sift_1))) { |
14160 | 9.72k | T tmp = nano::iter_move(sift); |
14161 | | |
14162 | 24.7k | do { |
14163 | 24.7k | *sift-- = nano::iter_move(sift_1); |
14164 | 24.7k | } while (sift != begin && |
14165 | 24.7k | nano::invoke(comp, nano::invoke(proj, tmp), |
14166 | 23.4k | nano::invoke(proj, *--sift_1))); |
14167 | | |
14168 | 9.72k | *sift = std::move(tmp); |
14169 | 9.72k | } |
14170 | 20.0k | } |
14171 | 5.23k | } |
14172 | | |
14173 | | // Sorts [begin, end) using insertion sort with the given comparison |
14174 | | // function. Assumes |
14175 | | // *(begin - 1) is an element smaller than or equal to any element in |
14176 | | // [begin, end). |
14177 | | template <typename I, typename Comp, typename Proj> |
14178 | | constexpr void unguarded_insertion_sort(I begin, |
14179 | | I end, |
14180 | | Comp& comp, |
14181 | | Proj& proj) |
14182 | 5.68k | { |
14183 | 5.68k | using T = iter_value_t<I>; |
14184 | | |
14185 | 5.68k | if (begin == end) { |
14186 | 1.71k | return; |
14187 | 1.71k | } |
14188 | | |
14189 | 34.0k | for (I cur = begin + 1; cur != end; ++cur) { |
14190 | 30.0k | I sift = cur; |
14191 | 30.0k | I sift_1 = cur - 1; |
14192 | | |
14193 | | // Compare first so we can avoid 2 moves for an element already |
14194 | | // positioned correctly. |
14195 | 30.0k | if (nano::invoke(comp, nano::invoke(proj, *sift), |
14196 | 30.0k | nano::invoke(proj, *sift_1))) { |
14197 | 8.56k | T tmp = nano::iter_move(sift); |
14198 | | |
14199 | 22.8k | do { |
14200 | 22.8k | *sift-- = nano::iter_move(sift_1); |
14201 | 22.8k | } while (nano::invoke(comp, nano::invoke(proj, tmp), |
14202 | 22.8k | nano::invoke(proj, *--sift_1))); |
14203 | | |
14204 | 8.56k | *sift = std::move(tmp); |
14205 | 8.56k | } |
14206 | 30.0k | } |
14207 | 3.97k | } |
14208 | | |
14209 | | // Attempts to use insertion sort on [begin, end). Will return false if more |
14210 | | // than partial_insertion_sort_limit elements were moved, and abort sorting. |
14211 | | // Otherwise it will successfully sort and return true. |
14212 | | template <typename I, typename Comp, typename Proj> |
14213 | | constexpr bool partial_insertion_sort(I begin, |
14214 | | I end, |
14215 | | Comp& comp, |
14216 | | Proj& proj) |
14217 | 804 | { |
14218 | 804 | using T = iter_value_t<I>; |
14219 | | |
14220 | 804 | if (begin == end) { |
14221 | 0 | return true; |
14222 | 0 | } |
14223 | | |
14224 | 804 | iter_difference_t<I> limit = 0; |
14225 | 10.0k | for (I cur = begin + 1; cur != end; ++cur) { |
14226 | 9.45k | if (limit > pqdsort_partial_insertion_sort_limit) { |
14227 | 162 | return false; |
14228 | 162 | } |
14229 | | |
14230 | 9.28k | I sift = cur; |
14231 | 9.28k | I sift_1 = cur - 1; |
14232 | | |
14233 | | // Compare first so we can avoid 2 moves for an element already |
14234 | | // positioned correctly. |
14235 | 9.28k | if (nano::invoke(comp, nano::invoke(proj, *sift), |
14236 | 9.28k | nano::invoke(proj, *sift_1))) { |
14237 | 1.66k | T tmp = nano::iter_move(sift); |
14238 | | |
14239 | 3.00k | do { |
14240 | 3.00k | *sift-- = nano::iter_move(sift_1); |
14241 | 3.00k | } while (sift != begin && |
14242 | 3.00k | nano::invoke(comp, nano::invoke(proj, tmp), |
14243 | 2.61k | nano::invoke(proj, *--sift_1))); |
14244 | | |
14245 | 1.66k | *sift = std::move(tmp); |
14246 | 1.66k | limit += cur - sift; |
14247 | 1.66k | } |
14248 | 9.28k | } |
14249 | | |
14250 | 642 | return true; |
14251 | 804 | } |
14252 | | |
14253 | | template <typename I, typename Comp, typename Proj> |
14254 | | constexpr void sort2(I a, I b, Comp& comp, Proj& proj) |
14255 | 48.7k | { |
14256 | 48.7k | if (nano::invoke(comp, nano::invoke(proj, *b), |
14257 | 48.7k | nano::invoke(proj, *a))) { |
14258 | 10.5k | nano::iter_swap(a, b); |
14259 | 10.5k | } |
14260 | 48.7k | } |
14261 | | |
14262 | | // Sorts the elements *a, *b and *c using comparison function comp. |
14263 | | template <typename I, typename Comp, typename Proj> |
14264 | | constexpr void sort3(I a, I b, I c, Comp& comp, Proj& proj) |
14265 | 16.2k | { |
14266 | 16.2k | sort2(a, b, comp, proj); |
14267 | 16.2k | sort2(b, c, comp, proj); |
14268 | 16.2k | sort2(a, b, comp, proj); |
14269 | 16.2k | } |
14270 | | |
14271 | | template <typename I> |
14272 | | constexpr void swap_offsets(I first, |
14273 | | I last, |
14274 | | unsigned char* offsets_l, |
14275 | | unsigned char* offsets_r, |
14276 | | int num, |
14277 | | bool use_swaps) |
14278 | 0 | { |
14279 | 0 | using T = iter_value_t<I>; |
14280 | 0 | if (use_swaps) { |
14281 | | // This case is needed for the descending distribution, where we |
14282 | | // need to have proper swapping for pdqsort to remain O(n). |
14283 | 0 | for (int i = 0; i < num; ++i) { |
14284 | 0 | nano::iter_swap(first + offsets_l[i], last - offsets_r[i]); |
14285 | 0 | } |
14286 | 0 | } |
14287 | 0 | else if (num > 0) { |
14288 | 0 | I l = first + offsets_l[0]; |
14289 | 0 | I r = last - offsets_r[0]; |
14290 | 0 | T tmp(nano::iter_move(l)); |
14291 | 0 | *l = nano::iter_move(r); |
14292 | |
|
14293 | 0 | for (int i = 1; i < num; ++i) { |
14294 | 0 | l = first + offsets_l[i]; |
14295 | 0 | *r = nano::iter_move(l); |
14296 | 0 | r = last - offsets_r[i]; |
14297 | 0 | *l = nano::iter_move(r); |
14298 | 0 | } |
14299 | 0 | *r = std::move(tmp); |
14300 | 0 | } |
14301 | 0 | } |
14302 | | |
14303 | | // Partitions [begin, end) around pivot *begin using comparison function |
14304 | | // comp. Elements equal to the pivot are put in the right-hand partition. |
14305 | | // Returns the position of the pivot after partitioning and whether the |
14306 | | // passed sequence already was correctly partitioned. Assumes the pivot is a |
14307 | | // median of at least 3 elements and that [begin, end) is at least |
14308 | | // insertion_sort_threshold long. Uses branchless partitioning. |
14309 | | template <typename I, typename Comp, typename Pred> |
14310 | | constexpr std::pair<I, bool> partition_right_branchless(I begin, |
14311 | | I end, |
14312 | | Comp& comp, |
14313 | | Pred& pred) |
14314 | 0 | { |
14315 | 0 | using T = iter_value_t<I>; |
14316 | | |
14317 | | // Move pivot into local for speed. |
14318 | 0 | T pivot(nano::iter_move(begin)); |
14319 | 0 | I first = begin; |
14320 | 0 | I last = end; |
14321 | | |
14322 | | // Find the first element greater than or equal than the pivot (the |
14323 | | // median of 3 guarantees this exists). |
14324 | 0 | while (nano::invoke(comp, nano::invoke(pred, *++first), |
14325 | 0 | nano::invoke(pred, pivot))) |
14326 | 0 | ; |
14327 | | |
14328 | | // Find the first element strictly smaller than the pivot. We have to |
14329 | | // guard this search if there was no element before *first. |
14330 | 0 | if (first - 1 == begin) { |
14331 | 0 | while (first < last && |
14332 | 0 | !nano::invoke(comp, nano::invoke(pred, *--last), |
14333 | 0 | nano::invoke(pred, pivot))) |
14334 | 0 | ; |
14335 | 0 | } |
14336 | 0 | else { |
14337 | 0 | while (!nano::invoke(comp, nano::invoke(pred, *--last), |
14338 | 0 | nano::invoke(pred, pivot))) |
14339 | 0 | ; |
14340 | 0 | } |
14341 | | |
14342 | | // If the first pair of elements that should be swapped to partition are |
14343 | | // the same element, the passed in sequence already was correctly |
14344 | | // partitioned. |
14345 | 0 | bool already_partitioned = first >= last; |
14346 | 0 | if (!already_partitioned) { |
14347 | 0 | nano::iter_swap(first, last); |
14348 | 0 | ++first; |
14349 | 0 | } |
14350 | | |
14351 | | // The following branchless partitioning is derived from |
14352 | | // "BlockQuicksort: How Branch Mispredictions don't affect Quicksort" by |
14353 | | // Stefan Edelkamp and Armin Weiss. |
14354 | 0 | alignas(pdqsort_cacheline_size) unsigned char |
14355 | 0 | offsets_l_storage[pdqsort_block_size] = {}; |
14356 | 0 | alignas(pdqsort_cacheline_size) unsigned char |
14357 | 0 | offsets_r_storage[pdqsort_block_size] = {}; |
14358 | 0 | unsigned char* offsets_l = offsets_l_storage; |
14359 | 0 | unsigned char* offsets_r = offsets_r_storage; |
14360 | 0 | int num_l = 0, num_r = 0, start_l = 0, start_r = 0; |
14361 | |
|
14362 | 0 | while (last - first > 2 * pdqsort_block_size) { |
14363 | | // Fill up offset blocks with elements that are on the wrong side. |
14364 | 0 | if (num_l == 0) { |
14365 | 0 | start_l = 0; |
14366 | 0 | I it = first; |
14367 | 0 | for (unsigned char i = 0; i < pdqsort_block_size;) { |
14368 | 0 | offsets_l[num_l] = i++; |
14369 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14370 | 0 | nano::invoke(pred, pivot)); |
14371 | 0 | ++it; |
14372 | 0 | offsets_l[num_l] = i++; |
14373 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14374 | 0 | nano::invoke(pred, pivot)); |
14375 | 0 | ++it; |
14376 | 0 | offsets_l[num_l] = i++; |
14377 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14378 | 0 | nano::invoke(pred, pivot)); |
14379 | 0 | ++it; |
14380 | 0 | offsets_l[num_l] = i++; |
14381 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14382 | 0 | nano::invoke(pred, pivot)); |
14383 | 0 | ++it; |
14384 | 0 | offsets_l[num_l] = i++; |
14385 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14386 | 0 | nano::invoke(pred, pivot)); |
14387 | 0 | ++it; |
14388 | 0 | offsets_l[num_l] = i++; |
14389 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14390 | 0 | nano::invoke(pred, pivot)); |
14391 | 0 | ++it; |
14392 | 0 | offsets_l[num_l] = i++; |
14393 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14394 | 0 | nano::invoke(pred, pivot)); |
14395 | 0 | ++it; |
14396 | 0 | offsets_l[num_l] = i++; |
14397 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14398 | 0 | nano::invoke(pred, pivot)); |
14399 | 0 | ++it; |
14400 | 0 | } |
14401 | 0 | } |
14402 | 0 | if (num_r == 0) { |
14403 | 0 | start_r = 0; |
14404 | 0 | I it = last; |
14405 | 0 | for (unsigned char i = 0; i < pdqsort_block_size;) { |
14406 | 0 | offsets_r[num_r] = ++i; |
14407 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14408 | 0 | nano::invoke(pred, pivot)); |
14409 | 0 | offsets_r[num_r] = ++i; |
14410 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14411 | 0 | nano::invoke(pred, pivot)); |
14412 | 0 | offsets_r[num_r] = ++i; |
14413 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14414 | 0 | nano::invoke(pred, pivot)); |
14415 | 0 | offsets_r[num_r] = ++i; |
14416 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14417 | 0 | nano::invoke(pred, pivot)); |
14418 | 0 | offsets_r[num_r] = ++i; |
14419 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14420 | 0 | nano::invoke(pred, pivot)); |
14421 | 0 | offsets_r[num_r] = ++i; |
14422 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14423 | 0 | nano::invoke(pred, pivot)); |
14424 | 0 | offsets_r[num_r] = ++i; |
14425 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14426 | 0 | nano::invoke(pred, pivot)); |
14427 | 0 | offsets_r[num_r] = ++i; |
14428 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14429 | 0 | nano::invoke(pred, pivot)); |
14430 | 0 | } |
14431 | 0 | } |
14432 | | |
14433 | | // Swap elements and update block sizes and first/last boundaries. |
14434 | 0 | int num = (nano::min)(num_l, num_r); |
14435 | 0 | swap_offsets(first, last, offsets_l + start_l, offsets_r + start_r, |
14436 | 0 | num, num_l == num_r); |
14437 | 0 | num_l -= num; |
14438 | 0 | num_r -= num; |
14439 | 0 | start_l += num; |
14440 | 0 | start_r += num; |
14441 | 0 | if (num_l == 0) |
14442 | 0 | first += pdqsort_block_size; |
14443 | 0 | if (num_r == 0) |
14444 | 0 | last -= pdqsort_block_size; |
14445 | 0 | } |
14446 | |
|
14447 | 0 | iter_difference_t<I> l_size = 0, r_size = 0; |
14448 | 0 | iter_difference_t<I> unknown_left = |
14449 | 0 | (last - first) - ((num_r || num_l) ? pdqsort_block_size : 0); |
14450 | 0 | if (num_r) { |
14451 | | // Handle leftover block by assigning the unknown elements to the |
14452 | | // other block. |
14453 | 0 | l_size = unknown_left; |
14454 | 0 | r_size = pdqsort_block_size; |
14455 | 0 | } |
14456 | 0 | else if (num_l) { |
14457 | 0 | l_size = pdqsort_block_size; |
14458 | 0 | r_size = unknown_left; |
14459 | 0 | } |
14460 | 0 | else { |
14461 | | // No leftover block, split the unknown elements in two blocks. |
14462 | 0 | l_size = unknown_left / 2; |
14463 | 0 | r_size = unknown_left - l_size; |
14464 | 0 | } |
14465 | | |
14466 | | // Fill offset buffers if needed. |
14467 | 0 | if (unknown_left && !num_l) { |
14468 | 0 | start_l = 0; |
14469 | 0 | I it = first; |
14470 | 0 | for (unsigned char i = 0; i < l_size;) { |
14471 | 0 | offsets_l[num_l] = i++; |
14472 | 0 | num_l += !nano::invoke(comp, nano::invoke(pred, *it), |
14473 | 0 | nano::invoke(pred, pivot)); |
14474 | 0 | ++it; |
14475 | 0 | } |
14476 | 0 | } |
14477 | 0 | if (unknown_left && !num_r) { |
14478 | 0 | start_r = 0; |
14479 | 0 | I it = last; |
14480 | 0 | for (unsigned char i = 0; i < r_size;) { |
14481 | 0 | offsets_r[num_r] = ++i; |
14482 | 0 | num_r += nano::invoke(comp, nano::invoke(pred, *--it), |
14483 | 0 | nano::invoke(pred, pivot)); |
14484 | 0 | } |
14485 | 0 | } |
14486 | |
|
14487 | 0 | int num = (nano::min)(num_l, num_r); |
14488 | 0 | swap_offsets(first, last, offsets_l + start_l, offsets_r + start_r, num, |
14489 | 0 | num_l == num_r); |
14490 | 0 | num_l -= num; |
14491 | 0 | num_r -= num; |
14492 | 0 | start_l += num; |
14493 | 0 | start_r += num; |
14494 | 0 | if (num_l == 0) |
14495 | 0 | first += l_size; |
14496 | 0 | if (num_r == 0) |
14497 | 0 | last -= r_size; |
14498 | | |
14499 | | // We have now fully identified [first, last)'s proper position. Swap |
14500 | | // the last elements. |
14501 | 0 | if (num_l) { |
14502 | 0 | offsets_l += start_l; |
14503 | 0 | while (num_l--) |
14504 | 0 | nano::iter_swap(first + offsets_l[num_l], --last); |
14505 | 0 | first = last; |
14506 | 0 | } |
14507 | 0 | if (num_r) { |
14508 | 0 | offsets_r += start_r; |
14509 | 0 | while (num_r--) |
14510 | 0 | nano::iter_swap(last - offsets_r[num_r], first), ++first; |
14511 | 0 | last = first; |
14512 | 0 | } |
14513 | | |
14514 | | // Put the pivot in the right place. |
14515 | 0 | I pivot_pos = first - 1; |
14516 | 0 | *begin = nano::iter_move(pivot_pos); |
14517 | 0 | *pivot_pos = std::move(pivot); |
14518 | |
|
14519 | 0 | return std::make_pair(std::move(pivot_pos), already_partitioned); |
14520 | 0 | } |
14521 | | |
14522 | | // Partitions [begin, end) around pivot *begin using comparison function |
14523 | | // comp. Elements equal to the pivot are put in the right-hand partition. |
14524 | | // Returns the position of the pivot after partitioning and whether the |
14525 | | // passed sequence already was correctly partitioned. Assumes the pivot is a |
14526 | | // median of at least 3 elements and that [begin, end) is at least |
14527 | | // insertion_sort_threshold long. |
14528 | | template <typename I, typename Comp, typename Proj> |
14529 | | constexpr std::pair<I, bool> partition_right(I begin, |
14530 | | I end, |
14531 | | Comp& comp, |
14532 | | Proj& proj) |
14533 | 6.35k | { |
14534 | 6.35k | using T = iter_value_t<I>; |
14535 | | |
14536 | | // Move pivot into local for speed. |
14537 | 6.35k | T pivot(nano::iter_move(begin)); |
14538 | | |
14539 | 6.35k | I first = begin; |
14540 | 6.35k | I last = end; |
14541 | | |
14542 | | // Find the first element greater than or equal than the pivot (the |
14543 | | // median of 3 guarantees this exists). |
14544 | 44.6k | while (nano::invoke(comp, nano::invoke(proj, *++first), |
14545 | 44.6k | nano::invoke(proj, pivot))) {} |
14546 | | |
14547 | | // Find the first element strictly smaller than the pivot. We have to |
14548 | | // guard this search if there was no element before *first. |
14549 | 6.35k | if (first - 1 == begin) { |
14550 | 184k | while (first < last && |
14551 | 184k | !nano::invoke(comp, nano::invoke(proj, *--last), |
14552 | 182k | nano::invoke(proj, pivot))) {} |
14553 | 3.82k | } |
14554 | 2.53k | else { |
14555 | 11.8k | while (!nano::invoke(comp, nano::invoke(proj, *--last), |
14556 | 11.8k | nano::invoke(proj, pivot))) {} |
14557 | 2.53k | } |
14558 | | |
14559 | | // If the first pair of elements that should be swapped to partition are |
14560 | | // the same element, the passed in sequence already was correctly |
14561 | | // partitioned. |
14562 | 6.35k | bool already_partitioned = first >= last; |
14563 | | |
14564 | | // Keep swapping pairs of elements that are on the wrong side of the |
14565 | | // pivot. Previously swapped pairs guard the searches, which is why the |
14566 | | // first iteration is special-cased above. |
14567 | 46.3k | while (first < last) { |
14568 | 39.9k | nano::iter_swap(first, last); |
14569 | 136k | while (nano::invoke(comp, nano::invoke(proj, *++first), |
14570 | 136k | nano::invoke(proj, pivot))) |
14571 | 96.0k | ; |
14572 | 121k | while (!nano::invoke(comp, nano::invoke(proj, *--last), |
14573 | 121k | nano::invoke(proj, pivot))) |
14574 | 81.4k | ; |
14575 | 39.9k | } |
14576 | | |
14577 | | // Put the pivot in the right place. |
14578 | 6.35k | I pivot_pos = first - 1; |
14579 | 6.35k | *begin = nano::iter_move(pivot_pos); |
14580 | 6.35k | *pivot_pos = std::move(pivot); |
14581 | | |
14582 | 6.35k | return std::make_pair(std::move(pivot_pos), already_partitioned); |
14583 | 6.35k | } |
14584 | | |
14585 | | // Similar function to the one above, except elements equal to the pivot are |
14586 | | // put to the left of the pivot and it doesn't check or return if the passed |
14587 | | // sequence already was partitioned. Since this is rarely used (the many |
14588 | | // equal case), and in that case pdqsort already has O(n) performance, no |
14589 | | // block quicksort is applied here for simplicity. |
14590 | | template <typename I, typename Comp, typename Proj> |
14591 | | constexpr I partition_left(I begin, I end, Comp& comp, Proj& proj) |
14592 | 2.79k | { |
14593 | 2.79k | using T = iter_value_t<I>; |
14594 | | |
14595 | 2.79k | T pivot(nano::iter_move(begin)); |
14596 | 2.79k | I first = begin; |
14597 | 2.79k | I last = end; |
14598 | | |
14599 | 5.13k | while (nano::invoke(comp, nano::invoke(proj, pivot), |
14600 | 5.13k | nano::invoke(proj, *--last))) |
14601 | 2.34k | ; |
14602 | | |
14603 | 2.79k | if (last + 1 == end) { |
14604 | 108k | while (first < last && |
14605 | 108k | !nano::invoke(comp, nano::invoke(proj, pivot), |
14606 | 107k | nano::invoke(proj, *++first))) |
14607 | 106k | ; |
14608 | 2.01k | } |
14609 | 774 | else { |
14610 | 8.26k | while (!nano::invoke(comp, nano::invoke(proj, pivot), |
14611 | 8.26k | nano::invoke(proj, *++first))) |
14612 | 7.48k | ; |
14613 | 774 | } |
14614 | | |
14615 | 18.5k | while (first < last) { |
14616 | 15.7k | nano::iter_swap(first, last); |
14617 | 24.6k | while (nano::invoke(comp, nano::invoke(proj, pivot), |
14618 | 24.6k | nano::invoke(proj, *--last))) |
14619 | 8.92k | ; |
14620 | 83.9k | while (!nano::invoke(comp, nano::invoke(proj, pivot), |
14621 | 83.9k | nano::invoke(proj, *++first))) |
14622 | 68.2k | ; |
14623 | 15.7k | } |
14624 | | |
14625 | 2.79k | I pivot_pos = last; |
14626 | 2.79k | *begin = nano::iter_move(pivot_pos); |
14627 | 2.79k | *pivot_pos = std::move(pivot); |
14628 | | |
14629 | 2.79k | return pivot_pos; |
14630 | 2.79k | } |
14631 | | |
14632 | | template <bool Branchless, typename I, typename Comp, typename Proj> |
14633 | | constexpr void pdqsort_loop(I begin, |
14634 | | I end, |
14635 | | Comp& comp, |
14636 | | Proj& proj, |
14637 | | int bad_allowed, |
14638 | | bool leftmost = true) |
14639 | 12.8k | { |
14640 | 12.8k | using diff_t = iter_difference_t<I>; |
14641 | | |
14642 | | // Use a while loop for tail recursion elimination. |
14643 | 21.5k | while (true) { |
14644 | 21.5k | diff_t size = nano::distance(begin, end); |
14645 | | |
14646 | | // Insertion sort is faster for small arrays. |
14647 | 21.5k | if (size < pdqsort_insertion_sort_threshold) { |
14648 | 12.4k | if (leftmost) { |
14649 | 6.72k | insertion_sort(begin, end, comp, proj); |
14650 | 6.72k | } |
14651 | 5.68k | else { |
14652 | 5.68k | unguarded_insertion_sort(begin, end, comp, proj); |
14653 | 5.68k | } |
14654 | 12.4k | return; |
14655 | 12.4k | } |
14656 | | |
14657 | | // Choose pivot as median of 3 or pseudomedian of 9. |
14658 | 9.14k | diff_t s2 = size / 2; |
14659 | 9.14k | if (size > pdqsort_ninther_threshold) { |
14660 | 2.37k | sort3(begin, begin + s2, end - 1, comp, proj); |
14661 | 2.37k | sort3(begin + 1, begin + (s2 - 1), end - 2, comp, proj); |
14662 | 2.37k | sort3(begin + 2, begin + (s2 + 1), end - 3, comp, proj); |
14663 | 2.37k | sort3(begin + (s2 - 1), begin + s2, begin + (s2 + 1), comp, |
14664 | 2.37k | proj); |
14665 | 2.37k | nano::iter_swap(begin, begin + s2); |
14666 | 2.37k | } |
14667 | 6.77k | else { |
14668 | 6.77k | sort3(begin + s2, begin, end - 1, comp, proj); |
14669 | 6.77k | } |
14670 | | |
14671 | | // If *(begin - 1) is the end of the right partition of a previous |
14672 | | // partition operation there is no element in [begin, end) that is |
14673 | | // smaller than *(begin - 1). Then if our pivot compares equal to |
14674 | | // *(begin - 1) we change strategy, putting equal elements in the |
14675 | | // left partition, greater elements in the right partition. We do |
14676 | | // not have to recurse on the left partition, since it's sorted (all |
14677 | | // equal). |
14678 | 9.14k | if (!leftmost && |
14679 | 9.14k | !nano::invoke(comp, nano::invoke(proj, *(begin - 1)), |
14680 | 4.84k | nano::invoke(proj, *begin))) { |
14681 | 2.79k | begin = partition_left(begin, end, comp, proj) + 1; |
14682 | 2.79k | continue; |
14683 | 2.79k | } |
14684 | | |
14685 | | // Partition and get results. |
14686 | 6.35k | std::pair<I, bool> part_result = |
14687 | 6.35k | Branchless ? partition_right_branchless(begin, end, comp, proj) |
14688 | 6.35k | : partition_right(begin, end, comp, proj); |
14689 | 6.35k | I pivot_pos = part_result.first; |
14690 | 6.35k | bool already_partitioned = part_result.second; |
14691 | | |
14692 | | // Check for a highly unbalanced partition. |
14693 | 6.35k | diff_t l_size = pivot_pos - begin; |
14694 | 6.35k | diff_t r_size = end - (pivot_pos + 1); |
14695 | 6.35k | bool highly_unbalanced = l_size < size / 8 || r_size < size / 8; |
14696 | | |
14697 | | // If we got a highly unbalanced partition we shuffle elements to |
14698 | | // break many patterns. |
14699 | 6.35k | if (highly_unbalanced) { |
14700 | | // If we had too many bad partitions, switch to heapsort to |
14701 | | // guarantee O(n log n). |
14702 | 3.97k | if (--bad_allowed == 0) { |
14703 | 162 | nano::make_heap(begin, end, comp, proj); |
14704 | 162 | nano::sort_heap(begin, end, comp, proj); |
14705 | 162 | return; |
14706 | 162 | } |
14707 | | |
14708 | 3.81k | if (l_size >= pdqsort_insertion_sort_threshold) { |
14709 | 708 | nano::iter_swap(begin, begin + l_size / 4); |
14710 | 708 | nano::iter_swap(pivot_pos - 1, pivot_pos - l_size / 4); |
14711 | | |
14712 | 708 | if (l_size > pdqsort_ninther_threshold) { |
14713 | 240 | nano::iter_swap(begin + 1, begin + (l_size / 4 + 1)); |
14714 | 240 | nano::iter_swap(begin + 2, begin + (l_size / 4 + 2)); |
14715 | 240 | nano::iter_swap(pivot_pos - 2, |
14716 | 240 | pivot_pos - (l_size / 4 + 1)); |
14717 | 240 | nano::iter_swap(pivot_pos - 3, |
14718 | 240 | pivot_pos - (l_size / 4 + 2)); |
14719 | 240 | } |
14720 | 708 | } |
14721 | | |
14722 | 3.81k | if (r_size >= pdqsort_insertion_sort_threshold) { |
14723 | 2.82k | nano::iter_swap(pivot_pos + 1, |
14724 | 2.82k | pivot_pos + (1 + r_size / 4)); |
14725 | 2.82k | nano::iter_swap(end - 1, end - r_size / 4); |
14726 | | |
14727 | 2.82k | if (r_size > pdqsort_ninther_threshold) { |
14728 | 750 | nano::iter_swap(pivot_pos + 2, |
14729 | 750 | pivot_pos + (2 + r_size / 4)); |
14730 | 750 | nano::iter_swap(pivot_pos + 3, |
14731 | 750 | pivot_pos + (3 + r_size / 4)); |
14732 | 750 | nano::iter_swap(end - 2, end - (1 + r_size / 4)); |
14733 | 750 | nano::iter_swap(end - 3, end - (2 + r_size / 4)); |
14734 | 750 | } |
14735 | 2.82k | } |
14736 | 3.81k | } |
14737 | 2.38k | else { |
14738 | | // If we were decently balanced and we tried to sort an already |
14739 | | // partitioned sequence try to use insertion sort. |
14740 | 2.38k | if (already_partitioned && |
14741 | 2.38k | partial_insertion_sort(begin, pivot_pos, comp, proj) && |
14742 | 2.38k | partial_insertion_sort(pivot_pos + 1, end, comp, proj)) |
14743 | 306 | return; |
14744 | 2.38k | } |
14745 | | |
14746 | | // Sort the left partition first using recursion and do tail |
14747 | | // recursion elimination for the right-hand partition. |
14748 | 5.88k | detail::pdqsort_loop<Branchless>(begin, pivot_pos, comp, proj, |
14749 | 5.88k | bad_allowed, leftmost); |
14750 | 5.88k | begin = pivot_pos + 1; |
14751 | 5.88k | leftmost = false; |
14752 | 5.88k | } |
14753 | 12.8k | } |
14754 | | |
14755 | | template <typename I, |
14756 | | typename Comp, |
14757 | | typename Proj, |
14758 | | bool Branchless = is_default_compare_v< |
14759 | | std::remove_const_t<Comp>>&& same_as<Proj, identity>&& |
14760 | | std::is_arithmetic<iter_value_t<I>>::value> |
14761 | | constexpr void pdqsort(I begin, I end, Comp& comp, Proj& proj) |
14762 | 6.99k | { |
14763 | 6.99k | if (begin == end) { |
14764 | 0 | return; |
14765 | 0 | } |
14766 | | |
14767 | 6.99k | detail::pdqsort_loop<Branchless>( |
14768 | 6.99k | std::move(begin), std::move(end), comp, proj, |
14769 | 6.99k | detail::log2(nano::distance(begin, end))); |
14770 | 6.99k | } |
14771 | | |
14772 | | } // namespace detail |
14773 | | |
14774 | | NANO_END_NAMESPACE |
14775 | | |
14776 | | #endif |
14777 | | |
14778 | | NANO_BEGIN_NAMESPACE |
14779 | | |
14780 | | namespace detail { |
14781 | | |
14782 | | struct sort_fn { |
14783 | | template <typename I, |
14784 | | typename S, |
14785 | | typename Comp = ranges::less, |
14786 | | typename Proj = identity> |
14787 | | constexpr std::enable_if_t<random_access_iterator<I> && |
14788 | | sentinel_for<S, I> && |
14789 | | sortable<I, Comp, Proj>, |
14790 | | I> |
14791 | | operator()(I first, |
14792 | | S last, |
14793 | | Comp comp = Comp{}, |
14794 | | Proj proj = Proj{}) const |
14795 | | { |
14796 | | I last_it = nano::next(first, last); |
14797 | | detail::pdqsort(std::move(first), last_it, comp, proj); |
14798 | | return last_it; |
14799 | | } |
14800 | | |
14801 | | template <typename Rng, |
14802 | | typename Comp = ranges::less, |
14803 | | typename Proj = identity> |
14804 | | constexpr std::enable_if_t<random_access_range<Rng> && |
14805 | | sortable<iterator_t<Rng>, Comp, Proj>, |
14806 | | borrowed_iterator_t<Rng>> |
14807 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
14808 | 6.99k | { |
14809 | 6.99k | iterator_t<Rng> last_it = |
14810 | 6.99k | nano::next(nano::begin(rng), nano::end(rng)); |
14811 | 6.99k | detail::pdqsort(nano::begin(rng), last_it, comp, proj); |
14812 | 6.99k | return last_it; |
14813 | 6.99k | } |
14814 | | }; |
14815 | | |
14816 | | } // namespace detail |
14817 | | |
14818 | | NANO_INLINE_VAR(detail::sort_fn, sort) |
14819 | | |
14820 | | NANO_END_NAMESPACE |
14821 | | |
14822 | | #endif |
14823 | | |
14824 | | // nanorange/algorithm/stl/stable_partition.hpp |
14825 | | // |
14826 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
14827 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
14828 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
14829 | | |
14830 | | //===-------------------------- algorithm ---------------------------------===// |
14831 | | // |
14832 | | // The LLVM Compiler Infrastructure |
14833 | | // |
14834 | | // This file is dual licensed under the MIT and the University of Illinois Open |
14835 | | // Source Licenses. See LICENSE.TXT for details. |
14836 | | // |
14837 | | //===----------------------------------------------------------------------===// |
14838 | | |
14839 | | #ifndef NANORANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED |
14840 | | #define NANORANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED |
14841 | | |
14842 | | NANO_BEGIN_NAMESPACE |
14843 | | |
14844 | | namespace detail { |
14845 | | |
14846 | | struct stable_partition_fn { |
14847 | | private: |
14848 | | template <typename I, typename Buf, typename Pred, typename Proj> |
14849 | | static subrange<I> impl_buffered(I first, |
14850 | | I last, |
14851 | | Buf& buf, |
14852 | | Pred& pred, |
14853 | | Proj& proj) |
14854 | | { |
14855 | | // first is known to be false, so pop it straight into the buffer |
14856 | | buf.push_back(nano::iter_move(first)); |
14857 | | |
14858 | | const auto res = nano::partition_copy( |
14859 | | nano::make_move_iterator(nano::next(first)), |
14860 | | nano::make_move_sentinel(--last), first, |
14861 | | nano::back_inserter(buf), std::ref(pred), std::ref(proj)); |
14862 | | |
14863 | | // last is known to be true, move that to the correct pos |
14864 | | first = std::move(res.out1); |
14865 | | *first = nano::iter_move(last); |
14866 | | ++first; |
14867 | | |
14868 | | // Now move all the other elements from the buffer back into the |
14869 | | // sequence |
14870 | | nano::move(buf, first); |
14871 | | return {std::move(first), std::move(last)}; |
14872 | | } |
14873 | | |
14874 | | // Note to self: this is a closed range, last is NOT past-the-end! |
14875 | | template <typename I, typename Pred, typename Proj> |
14876 | | static subrange<I> impl_unbuffered(I first, |
14877 | | I last, |
14878 | | iter_difference_t<I> dist, |
14879 | | Pred& pred, |
14880 | | Proj& proj) |
14881 | | { |
14882 | | using dist_t = iter_difference_t<I>; |
14883 | | |
14884 | | if (dist == 2) { |
14885 | | // We know first is false and last is true, so swap them |
14886 | | nano::iter_swap(first, last); |
14887 | | return {nano::next(first), nano::next(last)}; |
14888 | | } |
14889 | | |
14890 | | if (dist == 3) { |
14891 | | // We know first is false and last is true, so look at middle |
14892 | | I middle = nano::next(first); |
14893 | | |
14894 | | if (nano::invoke(pred, nano::invoke(proj, *middle))) { |
14895 | | nano::iter_swap(first, middle); |
14896 | | nano::iter_swap(middle, last); |
14897 | | return {nano::next(first, 2), nano::next(last)}; |
14898 | | } |
14899 | | |
14900 | | // middle is false |
14901 | | nano::iter_swap(middle, last); |
14902 | | nano::iter_swap(first, middle); |
14903 | | return {std::move(middle), std::next(last)}; |
14904 | | } |
14905 | | |
14906 | | const dist_t half = dist / 2; |
14907 | | const I middle = nano::next(first, half); |
14908 | | |
14909 | | I m1 = nano::prev(middle); |
14910 | | dist_t len_half = half; |
14911 | | |
14912 | | while (m1 != first && |
14913 | | !nano::invoke(pred, nano::invoke(proj, *m1))) { |
14914 | | --len_half; |
14915 | | --m1; |
14916 | | } |
14917 | | |
14918 | | const I first_false = |
14919 | | (m1 == first) |
14920 | | ? first |
14921 | | : impl_unbuffered(first, m1, len_half, pred, proj).begin(); |
14922 | | |
14923 | | m1 = middle; |
14924 | | len_half = dist - half; |
14925 | | |
14926 | | while (nano::invoke(pred, nano::invoke(proj, *m1))) { |
14927 | | if (++m1 == last) { |
14928 | | auto rot = nano::rotate(first_false, middle, ++last); |
14929 | | return {std::move(rot.begin()), nano::next(last)}; |
14930 | | } |
14931 | | } |
14932 | | |
14933 | | const I last_false = |
14934 | | impl_unbuffered(m1, last, len_half, pred, proj).begin(); |
14935 | | |
14936 | | auto rot = nano::rotate(first_false, middle, last_false); |
14937 | | return {rot.begin(), nano::next(last)}; |
14938 | | } |
14939 | | |
14940 | | template <typename I, typename Pred, typename Proj> |
14941 | | static subrange<I> impl(I first, I last, Pred& pred, Proj& proj) |
14942 | | { |
14943 | | // Find the first non-true value |
14944 | | first = nano::find_if_not(std::move(first), last, std::ref(pred), |
14945 | | std::ref(proj)); |
14946 | | if (first == last) { |
14947 | | return {std::move(first), std::move(last)}; |
14948 | | } |
14949 | | |
14950 | | // Find the last true value |
14951 | | I it = nano::find_if(nano::make_reverse_iterator(last), |
14952 | | nano::make_reverse_iterator(first), |
14953 | | std::ref(pred), std::ref(proj)) |
14954 | | .base(); |
14955 | | if (it == first) { |
14956 | | return {std::move(first), std::move(it)}; |
14957 | | } |
14958 | | |
14959 | | const auto dist = nano::distance(first, it); |
14960 | | |
14961 | | auto buf = detail::temporary_vector<iter_value_t<I>>(dist); |
14962 | | if (buf.capacity() < static_cast<std::size_t>(dist)) { |
14963 | | return {impl_unbuffered(first, --it, dist, pred, proj).begin(), |
14964 | | last}; |
14965 | | } |
14966 | | return {impl_buffered(first, it, buf, pred, proj).begin(), last}; |
14967 | | } |
14968 | | |
14969 | | template <typename I, typename S, typename Pred, typename Proj> |
14970 | | static std::enable_if_t<!same_as<I, S>, subrange<I>> impl(I first, |
14971 | | S last, |
14972 | | Pred& pred, |
14973 | | Proj& proj) |
14974 | | { |
14975 | | return impl(first, nano::next(first, last), pred, proj); |
14976 | | } |
14977 | | |
14978 | | public: |
14979 | | template <typename I, |
14980 | | typename S, |
14981 | | typename Pred, |
14982 | | typename Proj = identity> |
14983 | | std::enable_if_t< |
14984 | | bidirectional_iterator<I> && sentinel_for<S, I> && |
14985 | | indirect_unary_predicate<Pred, projected<I, Proj>> && |
14986 | | permutable<I>, |
14987 | | subrange<I>> |
14988 | | operator()(I first, S last, Pred pred, Proj proj = Proj{}) const |
14989 | | { |
14990 | | return stable_partition_fn::impl(std::move(first), std::move(last), |
14991 | | pred, proj); |
14992 | | } |
14993 | | |
14994 | | template <typename Rng, typename Pred, typename Proj = identity> |
14995 | | std::enable_if_t< |
14996 | | bidirectional_range<Rng> && |
14997 | | indirect_unary_predicate<Pred, |
14998 | | projected<iterator_t<Rng>, Proj>> && |
14999 | | permutable<iterator_t<Rng>>, |
15000 | | borrowed_subrange_t<Rng>> |
15001 | | operator()(Rng&& rng, Pred pred, Proj proj = Proj{}) const |
15002 | | { |
15003 | | return stable_partition_fn::impl(nano::begin(rng), nano::end(rng), |
15004 | | pred, proj); |
15005 | | } |
15006 | | }; |
15007 | | |
15008 | | } // namespace detail |
15009 | | |
15010 | | NANO_INLINE_VAR(detail::stable_partition_fn, stable_partition) |
15011 | | |
15012 | | NANO_END_NAMESPACE |
15013 | | |
15014 | | #endif |
15015 | | |
15016 | | // nanorange/algorithm/stable_sort.hpp |
15017 | | // |
15018 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
15019 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15020 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15021 | | |
15022 | | // Uses code from cmcstl2 - A concept-enabled C++ standard library |
15023 | | // |
15024 | | // Copyright Eric Niebler 2014 |
15025 | | // Copyright Casey Carter 2015 |
15026 | | // |
15027 | | |
15028 | | // |
15029 | | // Copyright (c) 1994 |
15030 | | // Hewlett-Packard Company |
15031 | | // |
15032 | | // Permission to use, copy, modify, distribute and sell this software |
15033 | | // and its documentation for any purpose is hereby granted without fee, |
15034 | | // provided that the above copyright notice appear in all copies and |
15035 | | // that both that copyright notice and this permission notice appear |
15036 | | // in supporting documentation. Hewlett-Packard Company makes no |
15037 | | // representations about the suitability of this software for any |
15038 | | // purpose. It is provided "as is" without express or implied warranty. |
15039 | | // |
15040 | | // Copyright (c) 1996 |
15041 | | // Silicon Graphics Computer Systems, Inc. |
15042 | | // |
15043 | | // Permission to use, copy, modify, distribute and sell this software |
15044 | | // and its documentation for any purpose is hereby granted without fee, |
15045 | | // provided that the above copyright notice appear in all copies and |
15046 | | // that both that copyright notice and this permission notice appear |
15047 | | // in supporting documentation. Silicon Graphics makes no |
15048 | | // representations about the suitability of this software for any |
15049 | | // purpose. It is provided "as is" without express or implied warranty. |
15050 | | |
15051 | | #ifndef NANORANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED |
15052 | | #define NANORANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED |
15053 | | |
15054 | | NANO_BEGIN_NAMESPACE |
15055 | | |
15056 | | namespace detail { |
15057 | | |
15058 | | struct stable_sort_fn { |
15059 | | private: |
15060 | | static constexpr int merge_sort_chunk_size = 7; |
15061 | | |
15062 | | template <typename I, typename Comp, typename Proj> |
15063 | | static void inplace_stable_sort(I first, I last, Comp& comp, Proj& proj) |
15064 | | { |
15065 | | if (last - first < 15) { |
15066 | | detail::insertion_sort(std::move(first), std::move(last), comp, |
15067 | | proj); |
15068 | | } |
15069 | | else { |
15070 | | I middle = first + iter_difference_t<I>(last - first) / 2; |
15071 | | inplace_stable_sort(first, middle, comp, proj); |
15072 | | inplace_stable_sort(middle, last, comp, proj); |
15073 | | inplace_merge_fn::impl_slow(first, middle, last, middle - first, |
15074 | | last - middle, comp, proj); |
15075 | | } |
15076 | | } |
15077 | | |
15078 | | template <typename I, typename Buf, typename Comp, typename Proj> |
15079 | | static void stable_sort_adaptive(I first, |
15080 | | I last, |
15081 | | Buf& buf, |
15082 | | Comp& comp, |
15083 | | Proj& proj) |
15084 | | { |
15085 | | auto len = iter_difference_t<I>((last - first + 1) / 2); |
15086 | | auto middle = first + len; |
15087 | | if (static_cast<std::size_t>(len) > buf.capacity()) { |
15088 | | stable_sort_adaptive(first, middle, buf, comp, proj); |
15089 | | stable_sort_adaptive(middle, last, buf, comp, proj); |
15090 | | } |
15091 | | else { |
15092 | | merge_sort_with_buffer(first, middle, buf, comp, proj); |
15093 | | merge_sort_with_buffer(middle, last, buf, comp, proj); |
15094 | | } |
15095 | | inplace_merge_fn::impl_buffered(first, middle, last, middle - first, |
15096 | | last - middle, buf, comp, proj); |
15097 | | } |
15098 | | |
15099 | | template <typename I, typename Buf, typename Comp, typename Proj> |
15100 | | static void merge_sort_with_buffer(I first, |
15101 | | I last, |
15102 | | Buf& buf, |
15103 | | Comp& comp, |
15104 | | Proj& proj) |
15105 | | { |
15106 | | auto len = iter_difference_t<I>(last - first); |
15107 | | auto step_size = iter_difference_t<I>(merge_sort_chunk_size); |
15108 | | chunk_insertion_sort(first, last, step_size, comp, proj); |
15109 | | if (step_size >= len) { |
15110 | | return; |
15111 | | } |
15112 | | assert(buf.empty()); |
15113 | | merge_sort_loop(first, last, nano::back_inserter(buf), step_size, |
15114 | | comp, proj); |
15115 | | step_size *= 2; |
15116 | | while (true) { |
15117 | | merge_sort_loop(buf.begin(), buf.end(), first, step_size, comp, |
15118 | | proj); |
15119 | | step_size *= 2; |
15120 | | if (step_size >= len) { |
15121 | | buf.clear(); |
15122 | | return; |
15123 | | } |
15124 | | merge_sort_loop(first, last, buf.begin(), step_size, comp, |
15125 | | proj); |
15126 | | step_size *= 2; |
15127 | | } |
15128 | | buf.clear(); |
15129 | | } |
15130 | | |
15131 | | template <typename I, typename Comp, typename Proj> |
15132 | | static void chunk_insertion_sort(I first, |
15133 | | I last, |
15134 | | iter_difference_t<I> chunk_size, |
15135 | | Comp& comp, |
15136 | | Proj& proj) |
15137 | | { |
15138 | | while (last - first >= chunk_size) { |
15139 | | detail::insertion_sort(first, first + chunk_size, comp, proj); |
15140 | | first += chunk_size; |
15141 | | } |
15142 | | detail::insertion_sort(first, last, comp, proj); |
15143 | | } |
15144 | | |
15145 | | template <typename I, typename O, typename Comp, typename Proj> |
15146 | | static void merge_sort_loop(I first, |
15147 | | I last, |
15148 | | O result, |
15149 | | iter_difference_t<I> step_size, |
15150 | | Comp& comp, |
15151 | | Proj& proj) |
15152 | | { |
15153 | | auto two_step = iter_difference_t<I>(2 * step_size); |
15154 | | while (last - first >= two_step) { |
15155 | | result = nano::merge( |
15156 | | nano::make_move_iterator(first), |
15157 | | nano::make_move_iterator(first + step_size), |
15158 | | nano::make_move_iterator(first + step_size), |
15159 | | nano::make_move_iterator(first + two_step), result, |
15160 | | std::ref(comp), std::ref(proj), std::ref(proj)) |
15161 | | .out; |
15162 | | first += two_step; |
15163 | | } |
15164 | | step_size = |
15165 | | nano::min(iter_difference_t<I>(last - first), step_size); |
15166 | | nano::merge(nano::make_move_iterator(first), |
15167 | | nano::make_move_iterator(first + step_size), |
15168 | | nano::make_move_iterator(first + step_size), |
15169 | | nano::make_move_iterator(last), result, std::ref(comp), |
15170 | | std::ref(proj), std::ref(proj)); |
15171 | | } |
15172 | | |
15173 | | template <typename I, typename Comp, typename Proj> |
15174 | | static void impl(I first, I last, Comp& comp, Proj& proj) |
15175 | | { |
15176 | | auto len = last - first; |
15177 | | if (len == 0) { |
15178 | | return; |
15179 | | } |
15180 | | |
15181 | | temporary_vector<iter_value_t<I>> buf(len > 256 ? len : 0); |
15182 | | |
15183 | | if (buf.capacity() != 0) { |
15184 | | stable_sort_adaptive(std::move(first), std::move(last), buf, |
15185 | | comp, proj); |
15186 | | } |
15187 | | else { |
15188 | | inplace_stable_sort(std::move(first), std::move(last), comp, |
15189 | | proj); |
15190 | | } |
15191 | | } |
15192 | | |
15193 | | public: |
15194 | | template <typename I, |
15195 | | typename S, |
15196 | | typename Comp = ranges::less, |
15197 | | typename Proj = identity> |
15198 | | std::enable_if_t<random_access_iterator<I> && sentinel_for<S, I> && |
15199 | | sortable<I, Comp, Proj>, |
15200 | | I> |
15201 | | operator()(I first, |
15202 | | S last, |
15203 | | Comp comp = Comp{}, |
15204 | | Proj proj = Proj{}) const |
15205 | | { |
15206 | | const auto ilast = nano::next(first, last); |
15207 | | impl(std::move(first), ilast, comp, proj); |
15208 | | return ilast; |
15209 | | } |
15210 | | |
15211 | | template <typename Rng, |
15212 | | typename Comp = ranges::less, |
15213 | | typename Proj = identity> |
15214 | | std::enable_if_t<random_access_range<Rng> && |
15215 | | sortable<iterator_t<Rng>, Comp, Proj>, |
15216 | | borrowed_iterator_t<Rng>> |
15217 | | operator()(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{}) const |
15218 | | { |
15219 | | auto first = nano::begin(rng); |
15220 | | const auto last = nano::next(first, nano::end(rng)); |
15221 | | impl(std::move(first), last, comp, proj); |
15222 | | return last; |
15223 | | } |
15224 | | }; |
15225 | | |
15226 | | } // namespace detail |
15227 | | |
15228 | | NANO_INLINE_VAR(detail::stable_sort_fn, stable_sort) |
15229 | | |
15230 | | NANO_END_NAMESPACE |
15231 | | |
15232 | | #endif |
15233 | | |
15234 | | // nanorange/algorithm/transform.hpp |
15235 | | // |
15236 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15237 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15238 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15239 | | |
15240 | | #ifndef NANORANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED |
15241 | | #define NANORANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED |
15242 | | |
15243 | | NANO_BEGIN_NAMESPACE |
15244 | | |
15245 | | template <typename I, typename O> |
15246 | | using unary_transform_result = in_out_result<I, O>; |
15247 | | |
15248 | | template <typename I1, typename I2, typename O> |
15249 | | using binary_transform_result = in_in_out_result<I1, I2, O>; |
15250 | | |
15251 | | namespace detail { |
15252 | | |
15253 | | struct transform_fn { |
15254 | | private: |
15255 | | template <typename I, typename S, typename O, typename F, typename Proj> |
15256 | | static constexpr unary_transform_result<I, O> unary_impl(I first, |
15257 | | S last, |
15258 | | O result, |
15259 | | F& op, |
15260 | | Proj& proj) |
15261 | 0 | { |
15262 | 0 | while (first != last) { |
15263 | 0 | *result = nano::invoke(op, nano::invoke(proj, *first)); |
15264 | 0 | ++first; |
15265 | 0 | ++result; |
15266 | 0 | } |
15267 | |
|
15268 | 0 | return {std::move(first), std::move(result)}; |
15269 | 0 | } Unexecuted instantiation: _ZN4nano6ranges6detail12transform_fn10unary_implINSt3__111__wrap_iterIPKNS4_9sub_matchIPKcEEEESC_NS5_IPNS4_8optionalIN3scn2v217basic_regex_matchIcEEEEEEZNSF_4impl23read_regex_matches_implIcNS4_17basic_string_viewIcNS4_11char_traitsIcEEEEEENSF_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSN_IT_NSO_ISX_EEEENSF_6detail11regex_flagsEST_RNSF_19basic_regex_matchesISX_EEEUlOSX_E_NS0_8identityEEENS0_13in_out_resultISX_T1_EESX_ST_S19_RT2_RT3_ Unexecuted instantiation: _ZN4nano6ranges6detail12transform_fn10unary_implINSt3__111__wrap_iterIPKNS4_9sub_matchIPKcEEEESC_NS5_IPNS4_8optionalIN3scn2v217basic_regex_matchIcEEEEEEZNSF_4impl23read_regex_matches_implIcNS0_9subrange_8subrangeIS8_S8_LNS0_13subrange_kindE1EEEEENSF_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENS4_17basic_string_viewIT_NS4_11char_traitsISY_EEEENSF_6detail11regex_flagsEST_RNSF_19basic_regex_matchesISY_EEEUlOSY_E_NS0_8identityEEENS0_13in_out_resultISY_T1_EESY_ST_S1B_RT2_RT3_ Unexecuted instantiation: _ZN4nano6ranges6detail12transform_fn10unary_implINSt3__111__wrap_iterIPKNS4_9sub_matchIPKwEEEESC_NS5_IPNS4_8optionalIN3scn2v217basic_regex_matchIwEEEEEEZNSF_4impl23read_regex_matches_implIwNS4_17basic_string_viewIwNS4_11char_traitsIwEEEEEENSF_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSN_IT_NSO_ISX_EEEENSF_6detail11regex_flagsEST_RNSF_19basic_regex_matchesISX_EEEUlOSX_E_NS0_8identityEEENS0_13in_out_resultISX_T1_EESX_ST_S19_RT2_RT3_ Unexecuted instantiation: _ZN4nano6ranges6detail12transform_fn10unary_implINSt3__111__wrap_iterIPKNS4_9sub_matchIPKwEEEESC_NS5_IPNS4_8optionalIN3scn2v217basic_regex_matchIwEEEEEEZNSF_4impl23read_regex_matches_implIwNS0_9subrange_8subrangeIS8_S8_LNS0_13subrange_kindE1EEEEENSF_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENS4_17basic_string_viewIT_NS4_11char_traitsISY_EEEENSF_6detail11regex_flagsEST_RNSF_19basic_regex_matchesISY_EEEUlOSY_E_NS0_8identityEEENS0_13in_out_resultISY_T1_EESY_ST_S1B_RT2_RT3_ |
15270 | | |
15271 | | template <typename I1, |
15272 | | typename S1, |
15273 | | typename I2, |
15274 | | typename O, |
15275 | | typename F, |
15276 | | typename Proj1, |
15277 | | typename Proj2> |
15278 | | static constexpr binary_transform_result<I1, I2, O> binary_impl3( |
15279 | | I1 first1, |
15280 | | S1 last1, |
15281 | | I2 first2, |
15282 | | O result, |
15283 | | F& op, |
15284 | | Proj1& proj1, |
15285 | | Proj2& proj2) |
15286 | | { |
15287 | | while (first1 != last1) { |
15288 | | *result = nano::invoke(op, nano::invoke(proj1, *first1), |
15289 | | nano::invoke(proj2, *first2)); |
15290 | | ++first1; |
15291 | | ++first2; |
15292 | | ++result; |
15293 | | } |
15294 | | |
15295 | | return {std::move(first1), std::move(first2), std::move(result)}; |
15296 | | } |
15297 | | |
15298 | | template <typename I1, |
15299 | | typename S1, |
15300 | | typename I2, |
15301 | | typename S2, |
15302 | | typename O, |
15303 | | typename F, |
15304 | | typename Proj1, |
15305 | | typename Proj2> |
15306 | | static constexpr binary_transform_result<I1, I2, O> binary_impl4( |
15307 | | I1 first1, |
15308 | | S1 last1, |
15309 | | I2 first2, |
15310 | | S2 last2, |
15311 | | O result, |
15312 | | F& op, |
15313 | | Proj1& proj1, |
15314 | | Proj2& proj2) |
15315 | | { |
15316 | | while (first1 != last1 && first2 != last2) { |
15317 | | *result = nano::invoke(op, nano::invoke(proj1, *first1), |
15318 | | nano::invoke(proj2, *first2)); |
15319 | | ++first1; |
15320 | | ++first2; |
15321 | | ++result; |
15322 | | } |
15323 | | |
15324 | | return {std::move(first1), std::move(first2), std::move(result)}; |
15325 | | } |
15326 | | |
15327 | | public: |
15328 | | // Unary op, iterators |
15329 | | template <typename I, |
15330 | | typename S, |
15331 | | typename O, |
15332 | | typename F, |
15333 | | typename Proj = identity> |
15334 | | constexpr std::enable_if_t< |
15335 | | input_iterator<I> && sentinel_for<S, I> && |
15336 | | weakly_incrementable<O> && copy_constructible<F> && |
15337 | | writable<O, indirect_result_t<F&, projected<I, Proj>>>, |
15338 | | unary_transform_result<I, O>> |
15339 | | operator()(I first, S last, O result, F op, Proj proj = Proj{}) const |
15340 | | { |
15341 | | return transform_fn::unary_impl(std::move(first), std::move(last), |
15342 | | std::move(result), op, proj); |
15343 | | } |
15344 | | |
15345 | | // Unary op, range |
15346 | | template <typename Rng, |
15347 | | typename O, |
15348 | | typename F, |
15349 | | typename Proj = identity> |
15350 | | constexpr std::enable_if_t< |
15351 | | input_range<Rng> && weakly_incrementable<O> && |
15352 | | copy_constructible<F> && |
15353 | | writable< |
15354 | | O, |
15355 | | indirect_result_t<F&, projected<iterator_t<Rng>, Proj>>>, |
15356 | | unary_transform_result<borrowed_iterator_t<Rng>, O>> |
15357 | | operator()(Rng&& rng, O result, F op, Proj proj = Proj{}) const |
15358 | 0 | { |
15359 | 0 | return transform_fn::unary_impl(nano::begin(rng), nano::end(rng), |
15360 | 0 | std::move(result), op, proj); |
15361 | 0 | } Unexecuted instantiation: _ZNK4nano6ranges6detail12transform_fnclIRNSt3__113match_resultsIPKcNS4_9allocatorINS4_9sub_matchIS7_EEEEEENS4_11__wrap_iterIPNS4_8optionalIN3scn2v217basic_regex_matchIcEEEEEEZNSH_4impl23read_regex_matches_implIcNS4_17basic_string_viewIcNS4_11char_traitsIcEEEEEENSH_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSP_IT_NSQ_ISZ_EEEENSH_6detail11regex_flagsESV_RNSH_19basic_regex_matchesISZ_EEEUlOSZ_E_NS0_8identityEEENS4_9enable_ifIXaaaaaa11input_rangeISZ_E20weakly_incrementableISV_E18copy_constructibleIT1_E8writableISV_NS1A_IXaa8readableINS1_11conditionalIX7same_asIT2_S19_EEE4typeIDTclL_ZNSU_5beginEEclsr3stdE7declvalIRSZ_EEEENS1_16projected_helperIS1H_S1D_vEEEEE9invocableIRS1B_NS1A_IXsr6detailE15dereferenceableIS1K_EEDTdeclsr3stdE7declvalIRS1K_EEEE4typeEEENS0_13invoke_resultIS1L_JS1P_EE4typeEE4typeEEENS0_13in_out_resultINS1C_IX14borrowed_rangeISZ_EEE4typeIS1H_NS0_8danglingEEESV_EEE4typeES17_SV_S1B_S1D_ Unexecuted instantiation: _ZNK4nano6ranges6detail12transform_fnclIRNSt3__113match_resultsIPKcNS4_9allocatorINS4_9sub_matchIS7_EEEEEENS4_11__wrap_iterIPNS4_8optionalIN3scn2v217basic_regex_matchIcEEEEEEZNSH_4impl23read_regex_matches_implIcNS0_9subrange_8subrangeIS7_S7_LNS0_13subrange_kindE1EEEEENSH_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENS4_17basic_string_viewIT_NS4_11char_traitsIS10_EEEENSH_6detail11regex_flagsESV_RNSH_19basic_regex_matchesIS10_EEEUlOS10_E_NS0_8identityEEENS4_9enable_ifIXaaaaaa11input_rangeIS10_E20weakly_incrementableISV_E18copy_constructibleIT1_E8writableISV_NS1C_IXaa8readableINS1_11conditionalIX7same_asIT2_S1B_EEE4typeIDTclL_ZNSU_5beginEEclsr3stdE7declvalIRS10_EEEENS1_16projected_helperIS1J_S1F_vEEEEE9invocableIRS1D_NS1C_IXsr6detailE15dereferenceableIS1M_EEDTdeclsr3stdE7declvalIRS1M_EEEE4typeEEENS0_13invoke_resultIS1N_JS1R_EE4typeEE4typeEEENS0_13in_out_resultINS1E_IX14borrowed_rangeIS10_EEE4typeIS1J_NS0_8danglingEEESV_EEE4typeES19_SV_S1D_S1F_ Unexecuted instantiation: _ZNK4nano6ranges6detail12transform_fnclIRNSt3__113match_resultsIPKwNS4_9allocatorINS4_9sub_matchIS7_EEEEEENS4_11__wrap_iterIPNS4_8optionalIN3scn2v217basic_regex_matchIwEEEEEEZNSH_4impl23read_regex_matches_implIwNS4_17basic_string_viewIwNS4_11char_traitsIwEEEEEENSH_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENSP_IT_NSQ_ISZ_EEEENSH_6detail11regex_flagsESV_RNSH_19basic_regex_matchesISZ_EEEUlOSZ_E_NS0_8identityEEENS4_9enable_ifIXaaaaaa11input_rangeISZ_E20weakly_incrementableISV_E18copy_constructibleIT1_E8writableISV_NS1A_IXaa8readableINS1_11conditionalIX7same_asIT2_S19_EEE4typeIDTclL_ZNSU_5beginEEclsr3stdE7declvalIRSZ_EEEENS1_16projected_helperIS1H_S1D_vEEEEE9invocableIRS1B_NS1A_IXsr6detailE15dereferenceableIS1K_EEDTdeclsr3stdE7declvalIRS1K_EEEE4typeEEENS0_13invoke_resultIS1L_JS1P_EE4typeEE4typeEEENS0_13in_out_resultINS1C_IX14borrowed_rangeISZ_EEE4typeIS1H_NS0_8danglingEEESV_EEE4typeES17_SV_S1B_S1D_ Unexecuted instantiation: _ZNK4nano6ranges6detail12transform_fnclIRNSt3__113match_resultsIPKwNS4_9allocatorINS4_9sub_matchIS7_EEEEEENS4_11__wrap_iterIPNS4_8optionalIN3scn2v217basic_regex_matchIwEEEEEEZNSH_4impl23read_regex_matches_implIwNS0_9subrange_8subrangeIS7_S7_LNS0_13subrange_kindE1EEEEENSH_13scan_expectedIDTclL_ZNS0_16function_objects5beginEEclsr3stdE7declvalIRT0_EEEEEENS4_17basic_string_viewIT_NS4_11char_traitsIS10_EEEENSH_6detail11regex_flagsESV_RNSH_19basic_regex_matchesIS10_EEEUlOS10_E_NS0_8identityEEENS4_9enable_ifIXaaaaaa11input_rangeIS10_E20weakly_incrementableISV_E18copy_constructibleIT1_E8writableISV_NS1C_IXaa8readableINS1_11conditionalIX7same_asIT2_S1B_EEE4typeIDTclL_ZNSU_5beginEEclsr3stdE7declvalIRS10_EEEENS1_16projected_helperIS1J_S1F_vEEEEE9invocableIRS1D_NS1C_IXsr6detailE15dereferenceableIS1M_EEDTdeclsr3stdE7declvalIRS1M_EEEE4typeEEENS0_13invoke_resultIS1N_JS1R_EE4typeEE4typeEEENS0_13in_out_resultINS1E_IX14borrowed_rangeIS10_EEE4typeIS1J_NS0_8danglingEEESV_EEE4typeES19_SV_S1D_S1F_ |
15362 | | |
15363 | | // Binary op, four-legged |
15364 | | template <typename I1, |
15365 | | typename S1, |
15366 | | typename I2, |
15367 | | typename S2, |
15368 | | typename O, |
15369 | | typename F, |
15370 | | typename Proj1 = identity, |
15371 | | typename Proj2 = identity> |
15372 | | constexpr std::enable_if_t< |
15373 | | input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> && |
15374 | | sentinel_for<S2, I2> && weakly_incrementable<O> && |
15375 | | copy_constructible<F> && |
15376 | | writable<O, |
15377 | | indirect_result_t<F&, |
15378 | | projected<I1, Proj1>, |
15379 | | projected<I2, Proj2>>>, |
15380 | | binary_transform_result<I1, I2, O>> |
15381 | | operator()(I1 first1, |
15382 | | S1 last1, |
15383 | | I2 first2, |
15384 | | S2 last2, |
15385 | | O result, |
15386 | | F op, |
15387 | | Proj1 proj1 = Proj1{}, |
15388 | | Proj2 proj2 = Proj2{}) const |
15389 | | { |
15390 | | return transform_fn::binary_impl4( |
15391 | | std::move(first1), std::move(last1), std::move(first2), |
15392 | | std::move(last2), std::move(result), op, proj1, proj2); |
15393 | | } |
15394 | | |
15395 | | // Binary op, two ranges |
15396 | | template <typename Rng1, |
15397 | | typename Rng2, |
15398 | | typename O, |
15399 | | typename F, |
15400 | | typename Proj1 = identity, |
15401 | | typename Proj2 = identity> |
15402 | | constexpr std::enable_if_t< |
15403 | | input_range<Rng1> && input_range<Rng2> && weakly_incrementable<O> && |
15404 | | copy_constructible<F> && |
15405 | | writable<O, |
15406 | | indirect_result_t<F&, |
15407 | | projected<iterator_t<Rng1>, Proj1>, |
15408 | | projected<iterator_t<Rng2>, Proj2>>>, |
15409 | | binary_transform_result<borrowed_iterator_t<Rng1>, |
15410 | | borrowed_iterator_t<Rng2>, |
15411 | | O>> |
15412 | | operator()(Rng1&& rng1, |
15413 | | Rng2&& rng2, |
15414 | | O result, |
15415 | | F op, |
15416 | | Proj1 proj1 = Proj1{}, |
15417 | | Proj2 proj2 = Proj2{}) const |
15418 | | { |
15419 | | return transform_fn::binary_impl4( |
15420 | | nano::begin(rng1), nano::end(rng1), nano::begin(rng2), |
15421 | | nano::end(rng2), std::move(result), op, proj1, proj2); |
15422 | | } |
15423 | | |
15424 | | // Binary op, three-legged |
15425 | | template <typename I1, |
15426 | | typename S1, |
15427 | | typename I2, |
15428 | | typename O, |
15429 | | typename F, |
15430 | | typename Proj1 = identity, |
15431 | | typename Proj2 = identity> |
15432 | | NANO_DEPRECATED constexpr std::enable_if_t< |
15433 | | input_iterator<I1> && sentinel_for<S1, I1> && |
15434 | | input_iterator<std::decay_t<I2>> && !input_range<I2> && |
15435 | | weakly_incrementable<O> && copy_constructible<F> && |
15436 | | writable<O, |
15437 | | indirect_result_t<F&, |
15438 | | projected<I1, Proj1>, |
15439 | | projected<std::decay_t<I2>, Proj2>>>, |
15440 | | binary_transform_result<I1, std::decay_t<I2>, O>> |
15441 | | operator()(I1 first1, |
15442 | | S1 last1, |
15443 | | I2&& first2, |
15444 | | O result, |
15445 | | F op, |
15446 | | Proj1 proj1 = Proj1{}, |
15447 | | Proj2 proj2 = Proj2{}) const |
15448 | | { |
15449 | | return transform_fn::binary_impl3( |
15450 | | std::move(first1), std::move(last1), std::forward<I2>(first2), |
15451 | | std::move(result), op, proj1, proj2); |
15452 | | } |
15453 | | |
15454 | | // binary op, range-and-a-half |
15455 | | template <typename Rng1, |
15456 | | typename I2, |
15457 | | typename O, |
15458 | | typename F, |
15459 | | typename Proj1 = identity, |
15460 | | typename Proj2 = identity> |
15461 | | NANO_DEPRECATED constexpr std::enable_if_t< |
15462 | | input_range<Rng1> && input_iterator<std::decay_t<I2>> && |
15463 | | !input_range<I2> && weakly_incrementable<O> && |
15464 | | copy_constructible<F> && |
15465 | | writable<O, |
15466 | | indirect_result_t<F&, |
15467 | | projected<iterator_t<Rng1>, Proj1>, |
15468 | | projected<std::decay_t<I2>, Proj2>>>, |
15469 | | binary_transform_result<borrowed_iterator_t<Rng1>, |
15470 | | std::decay_t<I2>, |
15471 | | O>> |
15472 | | operator()(Rng1&& rng1, |
15473 | | I2&& first2, |
15474 | | O result, |
15475 | | F op, |
15476 | | Proj1 proj1 = Proj1{}, |
15477 | | Proj2 proj2 = Proj2{}) const |
15478 | | { |
15479 | | return transform_fn::binary_impl3( |
15480 | | nano::begin(rng1), nano::end(rng1), std::forward<I2>(first2), |
15481 | | std::move(result), op, proj1, proj2); |
15482 | | } |
15483 | | }; |
15484 | | |
15485 | | } // namespace detail |
15486 | | |
15487 | | NANO_INLINE_VAR(detail::transform_fn, transform) |
15488 | | |
15489 | | NANO_END_NAMESPACE |
15490 | | |
15491 | | #endif |
15492 | | |
15493 | | // nanorange/algorithm/unique.hpp |
15494 | | // |
15495 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15496 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15497 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15498 | | |
15499 | | #ifndef NANORANGE_ALGORITHM_UNIQUE_HPP_INCLUDED |
15500 | | #define NANORANGE_ALGORITHM_UNIQUE_HPP_INCLUDED |
15501 | | |
15502 | | NANO_BEGIN_NAMESPACE |
15503 | | |
15504 | | namespace detail { |
15505 | | |
15506 | | struct unique_fn { |
15507 | | private: |
15508 | | template <typename I, typename S, typename R, typename Proj> |
15509 | | static constexpr subrange<I> impl(I first, S last, R& comp, Proj& proj) |
15510 | | { |
15511 | | I it = adjacent_find_fn::impl(first, last, comp, proj); |
15512 | | |
15513 | | if (it == last) { |
15514 | | return {it, std::move(it)}; |
15515 | | } |
15516 | | |
15517 | | I n = nano::next(it, 2, last); |
15518 | | for (; n != last; ++n) { |
15519 | | if (!nano::invoke(comp, nano::invoke(proj, *it), |
15520 | | nano::invoke(proj, *n))) { |
15521 | | *++it = iter_move(n); |
15522 | | } |
15523 | | } |
15524 | | |
15525 | | return {nano::next(it), std::move(n)}; |
15526 | | } |
15527 | | |
15528 | | public: |
15529 | | template <typename I, |
15530 | | typename S, |
15531 | | typename R = ranges::equal_to, |
15532 | | typename Proj = identity> |
15533 | | constexpr std::enable_if_t< |
15534 | | forward_iterator<I> && sentinel_for<S, I> && |
15535 | | indirect_relation<R, projected<I, Proj>> && permutable<I>, |
15536 | | subrange<I>> |
15537 | | operator()(I first, S last, R comp = {}, Proj proj = Proj{}) const |
15538 | | { |
15539 | | return unique_fn::impl(std::move(first), std::move(last), comp, |
15540 | | proj); |
15541 | | } |
15542 | | |
15543 | | template <typename Rng, |
15544 | | typename R = ranges::equal_to, |
15545 | | typename Proj = identity> |
15546 | | constexpr std::enable_if_t< |
15547 | | forward_range<Rng> && |
15548 | | indirect_relation<R, projected<iterator_t<Rng>, Proj>> && |
15549 | | permutable<iterator_t<Rng>>, |
15550 | | borrowed_subrange_t<Rng>> |
15551 | | operator()(Rng&& rng, R comp = {}, Proj proj = Proj{}) const |
15552 | | { |
15553 | | return unique_fn::impl(nano::begin(rng), nano::end(rng), comp, |
15554 | | proj); |
15555 | | } |
15556 | | }; |
15557 | | |
15558 | | } // namespace detail |
15559 | | |
15560 | | NANO_INLINE_VAR(detail::unique_fn, unique) |
15561 | | |
15562 | | NANO_END_NAMESPACE |
15563 | | |
15564 | | #endif |
15565 | | |
15566 | | // nanorange/algorithm/unique_copy.hpp |
15567 | | // |
15568 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15569 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15570 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15571 | | |
15572 | | #ifndef NANORANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED |
15573 | | #define NANORANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED |
15574 | | |
15575 | | NANO_BEGIN_NAMESPACE |
15576 | | |
15577 | | template <typename I, typename O> |
15578 | | using unique_copy_result = in_out_result<I, O>; |
15579 | | |
15580 | | namespace detail { |
15581 | | |
15582 | | struct unique_copy_fn { |
15583 | | private: |
15584 | | template <typename I, |
15585 | | typename S, |
15586 | | typename O, |
15587 | | typename Comp, |
15588 | | typename Proj> |
15589 | | static constexpr unique_copy_result<I, O> impl(I first, |
15590 | | S last, |
15591 | | O result, |
15592 | | Comp& comp, |
15593 | | Proj& proj) |
15594 | | { |
15595 | | if (first != last) { |
15596 | | iter_value_t<I> saved = *first; |
15597 | | *result = saved; |
15598 | | ++result; |
15599 | | |
15600 | | while (++first != last) { |
15601 | | auto&& v = *first; |
15602 | | if (!nano::invoke(comp, nano::invoke(proj, v), |
15603 | | nano::invoke(proj, saved))) { |
15604 | | saved = std::forward<decltype(v)>(v); |
15605 | | *result = saved; |
15606 | | ++result; |
15607 | | } |
15608 | | } |
15609 | | } |
15610 | | |
15611 | | return {std::move(first), std::move(result)}; |
15612 | | } |
15613 | | |
15614 | | template <typename I, typename O> |
15615 | | static auto constraint_helper(priority_tag<2>) |
15616 | | -> std::enable_if_t<forward_iterator<I>, std::true_type>; |
15617 | | |
15618 | | template <typename I, typename O> |
15619 | | static auto constraint_helper(priority_tag<1>) |
15620 | | -> std::enable_if_t<input_iterator<O> && |
15621 | | same_as<iter_value_t<I>, iter_value_t<O>>, |
15622 | | std::true_type>; |
15623 | | |
15624 | | template <typename I, typename O> |
15625 | | static auto constraint_helper(priority_tag<0>) |
15626 | | -> std::enable_if_t<indirectly_copyable_storable<I, O>, |
15627 | | std::true_type>; |
15628 | | |
15629 | | public: |
15630 | | template <typename I, |
15631 | | typename S, |
15632 | | typename O, |
15633 | | typename Comp = ranges::equal_to, |
15634 | | typename Proj = identity> |
15635 | | constexpr auto operator()(I first, |
15636 | | S last, |
15637 | | O result, |
15638 | | Comp comp = Comp{}, |
15639 | | Proj proj = Proj{}) const |
15640 | | -> std::enable_if_t< |
15641 | | input_iterator<I> && sentinel_for<S, I> && |
15642 | | weakly_incrementable<O> && |
15643 | | indirect_relation<Comp, projected<I, Proj>> && |
15644 | | indirectly_copyable<I, O>&& decltype(constraint_helper<I, |
15645 | | O>( |
15646 | | priority_tag<2>{}))::value, |
15647 | | unique_copy_result<I, O>> |
15648 | | { |
15649 | | return unique_copy_fn::impl(std::move(first), std::move(last), |
15650 | | std::move(result), comp, proj); |
15651 | | } |
15652 | | |
15653 | | template <typename Rng, |
15654 | | typename O, |
15655 | | typename Comp = ranges::equal_to, |
15656 | | typename Proj = identity> |
15657 | | constexpr auto operator()(Rng&& rng, |
15658 | | O result, |
15659 | | Comp comp = Comp{}, |
15660 | | Proj proj = Proj{}) const |
15661 | | -> std::enable_if_t< |
15662 | | input_range<Rng> && weakly_incrementable<O> && |
15663 | | indirect_relation<Comp, projected<iterator_t<Rng>, Proj>> && |
15664 | | indirectly_copyable< |
15665 | | iterator_t<Rng>, |
15666 | | O>&& decltype(constraint_helper<iterator_t<Rng>, |
15667 | | O>( |
15668 | | priority_tag<2>{}))::value, |
15669 | | unique_copy_result<borrowed_iterator_t<Rng>, O>> |
15670 | | { |
15671 | | return unique_copy_fn::impl(nano::begin(rng), nano::end(rng), |
15672 | | std::move(result), comp, proj); |
15673 | | } |
15674 | | }; |
15675 | | |
15676 | | } // namespace detail |
15677 | | |
15678 | | NANO_INLINE_VAR(detail::unique_copy_fn, unique_copy) |
15679 | | |
15680 | | NANO_END_NAMESPACE |
15681 | | |
15682 | | #endif |
15683 | | |
15684 | | #endif |
15685 | | |
15686 | | // nanorange/iterator.hpp |
15687 | | // |
15688 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15689 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15690 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15691 | | |
15692 | | #ifndef NANORANGE_ITERATOR_HPP_INCLUDED |
15693 | | #define NANORANGE_ITERATOR_HPP_INCLUDED |
15694 | | |
15695 | | // nanorange/iterator/front_insert_iterator.hpp |
15696 | | // |
15697 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15698 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15699 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15700 | | |
15701 | | #ifndef NANORANGE_ITERATOR_FRONT_INSERT_ITERATOR_HPP_INCLUDED |
15702 | | #define NANORANGE_ITERATOR_FRONT_INSERT_ITERATOR_HPP_INCLUDED |
15703 | | |
15704 | | #include <iterator> |
15705 | | |
15706 | | NANO_BEGIN_NAMESPACE |
15707 | | |
15708 | | template <typename Container> |
15709 | | struct front_insert_iterator { |
15710 | | using container_type = Container; |
15711 | | using difference_type = std::ptrdiff_t; |
15712 | | |
15713 | | constexpr front_insert_iterator() = default; |
15714 | | |
15715 | | explicit front_insert_iterator(Container& x) : cont_(std::addressof(x)) {} |
15716 | | |
15717 | | front_insert_iterator& operator=(const iter_value_t<Container>& value) |
15718 | | { |
15719 | | cont_->push_front(value); |
15720 | | return *this; |
15721 | | } |
15722 | | |
15723 | | front_insert_iterator& operator=(iter_value_t<Container>&& value) |
15724 | | { |
15725 | | cont_->push_front(std::move(value)); |
15726 | | return *this; |
15727 | | } |
15728 | | |
15729 | | front_insert_iterator& operator*() |
15730 | | { |
15731 | | return *this; |
15732 | | } |
15733 | | front_insert_iterator& operator++() |
15734 | | { |
15735 | | return *this; |
15736 | | } |
15737 | | front_insert_iterator& operator++(int) |
15738 | | { |
15739 | | return *this; |
15740 | | } |
15741 | | |
15742 | | private: |
15743 | | container_type* cont_ = nullptr; |
15744 | | }; |
15745 | | |
15746 | | template <typename Container> |
15747 | | front_insert_iterator<Container> front_inserter(Container& x) |
15748 | | { |
15749 | | return front_insert_iterator<Container>(x); |
15750 | | } |
15751 | | |
15752 | | NANO_END_NAMESPACE |
15753 | | |
15754 | | namespace std { |
15755 | | |
15756 | | template <typename Cont> |
15757 | | struct iterator_traits<::nano::front_insert_iterator<Cont>> { |
15758 | | using value_type = void; |
15759 | | using difference_type = ptrdiff_t; |
15760 | | using reference = void; |
15761 | | using pointer = void; |
15762 | | using iterator_category = output_iterator_tag; |
15763 | | }; |
15764 | | |
15765 | | } // namespace std |
15766 | | |
15767 | | #endif |
15768 | | |
15769 | | // nanorange/iterator/insert_iterator.hpp |
15770 | | // |
15771 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15772 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15773 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15774 | | |
15775 | | #ifndef NANORANGE_ITERATOR_INSERT_ITERATOR_HPP_INCLUDED |
15776 | | #define NANORANGE_ITERATOR_INSERT_ITERATOR_HPP_INCLUDED |
15777 | | |
15778 | | #include <iterator> |
15779 | | |
15780 | | NANO_BEGIN_NAMESPACE |
15781 | | |
15782 | | template <typename Container> |
15783 | | struct insert_iterator { |
15784 | | using container_type = Container; |
15785 | | using difference_type = std::ptrdiff_t; |
15786 | | |
15787 | | constexpr insert_iterator() = default; |
15788 | | |
15789 | | explicit insert_iterator(Container& x, iterator_t<Container> i) |
15790 | | : cont_(std::addressof(x)), it_(i) |
15791 | | { |
15792 | | } |
15793 | | |
15794 | | insert_iterator& operator=(const iter_value_t<Container>& value) |
15795 | | { |
15796 | | cont_->insert(it_, value); |
15797 | | ++it_; |
15798 | | return *this; |
15799 | | } |
15800 | | |
15801 | | insert_iterator& operator=(iter_value_t<Container>&& value) |
15802 | | { |
15803 | | cont_->push_back(it_, std::move(value)); |
15804 | | ++it_; |
15805 | | return *this; |
15806 | | } |
15807 | | |
15808 | | insert_iterator& operator*() |
15809 | | { |
15810 | | return *this; |
15811 | | } |
15812 | | insert_iterator& operator++() |
15813 | | { |
15814 | | return *this; |
15815 | | } |
15816 | | insert_iterator& operator++(int) |
15817 | | { |
15818 | | return *this; |
15819 | | } |
15820 | | |
15821 | | private: |
15822 | | container_type* cont_ = nullptr; |
15823 | | iterator_t<container_type> it_{}; |
15824 | | }; |
15825 | | |
15826 | | template <typename Container> |
15827 | | insert_iterator<Container> inserter(Container& x) |
15828 | | { |
15829 | | return back_insert_iterator<Container>(x); |
15830 | | } |
15831 | | |
15832 | | NANO_END_NAMESPACE |
15833 | | |
15834 | | namespace std { |
15835 | | |
15836 | | template <typename Container> |
15837 | | struct iterator_traits<::nano::insert_iterator<Container>> { |
15838 | | using value_type = void; |
15839 | | using difference_type = ptrdiff_t; |
15840 | | using reference = void; |
15841 | | using pointer = void; |
15842 | | using iterator_category = output_iterator_tag; |
15843 | | }; |
15844 | | |
15845 | | } // namespace std |
15846 | | |
15847 | | #endif |
15848 | | // nanorange/iterator/istream_iterator.hpp |
15849 | | // |
15850 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15851 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15852 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15853 | | |
15854 | | #ifndef NANORANGE_ITERATOR_ISTREAM_ITERATOR_HPP_INCLUDED |
15855 | | #define NANORANGE_ITERATOR_ISTREAM_ITERATOR_HPP_INCLUDED |
15856 | | |
15857 | | #include <iosfwd> |
15858 | | |
15859 | | NANO_BEGIN_NAMESPACE |
15860 | | |
15861 | | template <typename T, |
15862 | | typename CharT = char, |
15863 | | typename Traits = std::char_traits<CharT>, |
15864 | | typename Distance = std::ptrdiff_t> |
15865 | | class istream_iterator { |
15866 | | public: |
15867 | | using iterator_category = input_iterator_tag; |
15868 | | using difference_type = Distance; |
15869 | | using value_type = T; |
15870 | | using reference = const T&; |
15871 | | using pointer = const T*; |
15872 | | using char_type = CharT; |
15873 | | using traits_type = Traits; |
15874 | | using istream_type = std::basic_istream<CharT, Traits>; |
15875 | | |
15876 | | constexpr istream_iterator() = default; |
15877 | | |
15878 | | constexpr istream_iterator(default_sentinel_t) {} |
15879 | | |
15880 | | istream_iterator(istream_type& s) : in_stream_(std::addressof(s)) |
15881 | | { |
15882 | | s >> value_; |
15883 | | } |
15884 | | |
15885 | | istream_iterator(const istream_iterator& x) = default; |
15886 | | |
15887 | | ~istream_iterator() = default; |
15888 | | |
15889 | | const T& operator*() const |
15890 | | { |
15891 | | return value_; |
15892 | | } |
15893 | | |
15894 | | const T* operator->() const |
15895 | | { |
15896 | | return std::addressof(value_); |
15897 | | } |
15898 | | |
15899 | | istream_iterator& operator++() |
15900 | | { |
15901 | | *in_stream_ >> value_; |
15902 | | if (in_stream_->fail()) { |
15903 | | in_stream_ = nullptr; |
15904 | | } |
15905 | | return *this; |
15906 | | } |
15907 | | |
15908 | | istream_iterator operator++(int) |
15909 | | { |
15910 | | istream_iterator tmp = *this; |
15911 | | this->operator++(); |
15912 | | return tmp; |
15913 | | } |
15914 | | |
15915 | | friend bool operator==(const istream_iterator& x, const istream_iterator& y) |
15916 | | { |
15917 | | return x.in_stream_ == y.in_stream_; |
15918 | | } |
15919 | | |
15920 | | friend bool operator==(default_sentinel_t, const istream_iterator y) |
15921 | | { |
15922 | | return nullptr == y.in_stream_; |
15923 | | } |
15924 | | |
15925 | | friend bool operator==(const istream_iterator& x, default_sentinel_t) |
15926 | | { |
15927 | | return x.in_stream_ == nullptr; |
15928 | | } |
15929 | | |
15930 | | friend bool operator!=(const istream_iterator& x, const istream_iterator& y) |
15931 | | { |
15932 | | return !(x == y); |
15933 | | } |
15934 | | |
15935 | | friend bool operator!=(default_sentinel_t x, const istream_iterator y) |
15936 | | { |
15937 | | return !(x == y); |
15938 | | } |
15939 | | |
15940 | | friend bool operator!=(const istream_iterator& x, default_sentinel_t y) |
15941 | | { |
15942 | | return !(x == y); |
15943 | | } |
15944 | | |
15945 | | private: |
15946 | | istream_type* in_stream_ = nullptr; |
15947 | | T value_{}; |
15948 | | }; |
15949 | | |
15950 | | NANO_END_NAMESPACE |
15951 | | |
15952 | | #endif |
15953 | | |
15954 | | // nanorange/iterator/istreambuf_iterator.hpp |
15955 | | // |
15956 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
15957 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
15958 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
15959 | | |
15960 | | #ifndef NANORANGE_ITERATOR_ISTREAMBUF_ITERATOR_HPP_INCLUDED |
15961 | | #define NANORANGE_ITERATOR_ISTREAMBUF_ITERATOR_HPP_INCLUDED |
15962 | | |
15963 | | #include <iosfwd> |
15964 | | |
15965 | | NANO_BEGIN_NAMESPACE |
15966 | | |
15967 | | template <typename CharT, typename Traits = std::char_traits<CharT>> |
15968 | | class istreambuf_iterator { |
15969 | | class proxy { |
15970 | | friend class istreambuf_iterator; |
15971 | | CharT keep_; |
15972 | | std::basic_streambuf<CharT, Traits>* sbuf_; |
15973 | | |
15974 | | proxy(CharT c, std::basic_streambuf<CharT, Traits>* sbuf) |
15975 | | : keep_(c), sbuf_(sbuf) |
15976 | | { |
15977 | | } |
15978 | | |
15979 | | public: |
15980 | | CharT operator*() const |
15981 | | { |
15982 | | return keep_; |
15983 | | } |
15984 | | }; |
15985 | | |
15986 | | public: |
15987 | | using iterator_category = input_iterator_tag; |
15988 | | using value_type = CharT; |
15989 | | using difference_type = typename Traits::off_type; |
15990 | | using reference = CharT; |
15991 | | using pointer = CharT*; |
15992 | | using char_type = CharT; |
15993 | | using traits_type = Traits; |
15994 | | using int_type = typename Traits::int_type; |
15995 | | using streambuf_type = std::basic_streambuf<CharT, Traits>; |
15996 | | using istream_type = std::basic_istream<CharT, Traits>; |
15997 | | |
15998 | | constexpr istreambuf_iterator() noexcept = default; |
15999 | | |
16000 | | constexpr istreambuf_iterator(default_sentinel_t) noexcept {} |
16001 | | |
16002 | | istreambuf_iterator(const istreambuf_iterator&) noexcept = default; |
16003 | | |
16004 | | ~istreambuf_iterator() = default; |
16005 | | |
16006 | | istreambuf_iterator(istream_type& s) noexcept : sbuf_(s.rdbuf()) {} |
16007 | | |
16008 | | istreambuf_iterator(streambuf_type* s) noexcept : sbuf_(s) {} |
16009 | | |
16010 | | istreambuf_iterator(const proxy& p) noexcept : sbuf_(p.sbuf_) {} |
16011 | | |
16012 | | char_type operator*() const |
16013 | | { |
16014 | | return Traits::to_char_type(sbuf_->sgetc()); |
16015 | | } |
16016 | | |
16017 | | istreambuf_iterator& operator++() |
16018 | | { |
16019 | | sbuf_->sbumpc(); |
16020 | | return *this; |
16021 | | } |
16022 | | |
16023 | | proxy operator++(int) |
16024 | | { |
16025 | | return proxy(Traits::to_char_type(sbuf_->sbumpc()), sbuf_); |
16026 | | } |
16027 | | |
16028 | | bool equal(const istreambuf_iterator& b) const |
16029 | | { |
16030 | | return is_eof() == b.is_eof(); |
16031 | | } |
16032 | | |
16033 | | private: |
16034 | | bool is_eof() const |
16035 | | { |
16036 | | if (sbuf_ && sbuf_->sgetc() == Traits::eof()) { |
16037 | | sbuf_ = nullptr; |
16038 | | return true; |
16039 | | } |
16040 | | |
16041 | | return sbuf_ == nullptr; |
16042 | | } |
16043 | | |
16044 | | mutable streambuf_type* sbuf_ = nullptr; |
16045 | | }; |
16046 | | |
16047 | | template <typename CharT, typename Traits> |
16048 | | bool operator==(const istreambuf_iterator<CharT, Traits>& a, |
16049 | | const istreambuf_iterator<CharT, Traits>& b) |
16050 | | { |
16051 | | return a.equal(b); |
16052 | | } |
16053 | | |
16054 | | template <typename CharT, typename Traits> |
16055 | | bool operator==(default_sentinel_t, const istreambuf_iterator<CharT, Traits>& b) |
16056 | | { |
16057 | | return istreambuf_iterator<CharT, Traits>{}.equal(b); |
16058 | | } |
16059 | | |
16060 | | template <typename CharT, typename Traits> |
16061 | | bool operator==(const istreambuf_iterator<CharT, Traits>& a, default_sentinel_t) |
16062 | | { |
16063 | | return a.equal(istreambuf_iterator<CharT, Traits>{}); |
16064 | | } |
16065 | | |
16066 | | template <typename CharT, typename Traits> |
16067 | | bool operator!=(const istreambuf_iterator<CharT, Traits>& a, |
16068 | | const istreambuf_iterator<CharT, Traits>& b) |
16069 | | { |
16070 | | return !(a == b); |
16071 | | } |
16072 | | |
16073 | | template <typename CharT, typename Traits> |
16074 | | bool operator!=(default_sentinel_t a, |
16075 | | const istreambuf_iterator<CharT, Traits>& b) |
16076 | | { |
16077 | | return !(a == b); |
16078 | | } |
16079 | | |
16080 | | template <typename CharT, typename Traits> |
16081 | | bool operator!=(const istreambuf_iterator<CharT, Traits>& a, |
16082 | | default_sentinel_t b) |
16083 | | { |
16084 | | return !(a == b); |
16085 | | } |
16086 | | |
16087 | | NANO_END_NAMESPACE |
16088 | | |
16089 | | #endif |
16090 | | |
16091 | | // nanorange/iterator/ostream_iterator.hpp |
16092 | | // |
16093 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16094 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16095 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16096 | | |
16097 | | #ifndef NANORANGE_ITERATOR_OSTREAM_ITERATOR_HPP_INCLUDED |
16098 | | #define NANORANGE_ITERATOR_OSTREAM_ITERATOR_HPP_INCLUDED |
16099 | | |
16100 | | #include <iosfwd> |
16101 | | #include <iterator> |
16102 | | #include <memory> |
16103 | | |
16104 | | NANO_BEGIN_NAMESPACE |
16105 | | |
16106 | | template <typename T, |
16107 | | typename CharT = char, |
16108 | | typename Traits = std::char_traits<CharT>> |
16109 | | struct ostream_iterator { |
16110 | | using char_type = CharT; |
16111 | | using traits_type = Traits; |
16112 | | using ostream_type = std::basic_ostream<CharT, Traits>; |
16113 | | using difference_type = std::ptrdiff_t; |
16114 | | |
16115 | | constexpr ostream_iterator() noexcept = default; |
16116 | | |
16117 | | ostream_iterator(ostream_type& os, const CharT* delim = nullptr) noexcept |
16118 | | : os_(std::addressof(os)), delim_(delim) |
16119 | | { |
16120 | | } |
16121 | | |
16122 | | ostream_iterator& operator=(const T& value) |
16123 | | { |
16124 | | *os_ << value; |
16125 | | if (delim_) { |
16126 | | *os_ << delim_; |
16127 | | } |
16128 | | return *this; |
16129 | | } |
16130 | | |
16131 | | ostream_iterator& operator*() |
16132 | | { |
16133 | | return *this; |
16134 | | } |
16135 | | ostream_iterator& operator++() |
16136 | | { |
16137 | | return *this; |
16138 | | } |
16139 | | ostream_iterator& operator++(int) |
16140 | | { |
16141 | | return *this; |
16142 | | } |
16143 | | |
16144 | | private: |
16145 | | ostream_type* os_ = nullptr; |
16146 | | const char_type* delim_ = nullptr; |
16147 | | }; |
16148 | | |
16149 | | NANO_END_NAMESPACE |
16150 | | |
16151 | | namespace std { |
16152 | | |
16153 | | template <typename T, typename C, typename Tr> |
16154 | | struct iterator_traits<::nano::ranges::ostream_iterator<T, C, Tr>> { |
16155 | | using value_type = void; |
16156 | | using difference_type = ptrdiff_t; |
16157 | | using reference = void; |
16158 | | using pointer = void; |
16159 | | using iterator_category = std::output_iterator_tag; |
16160 | | }; |
16161 | | |
16162 | | } // namespace std |
16163 | | |
16164 | | #endif |
16165 | | // nanorange/iterator/ostreambuf_iterator.hpp |
16166 | | // |
16167 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16168 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16169 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16170 | | |
16171 | | #ifndef NANORANGE_ITERATOR_OSTREAMBUF_ITERATOR_HPP_INCLUDED |
16172 | | #define NANORANGE_ITERATOR_OSTREAMBUF_ITERATOR_HPP_INCLUDED |
16173 | | |
16174 | | #include <iosfwd> // for basic_streambuf |
16175 | | #include <iterator> |
16176 | | |
16177 | | NANO_BEGIN_NAMESPACE |
16178 | | |
16179 | | template <typename CharT, typename Traits = std::char_traits<CharT>> |
16180 | | struct ostreambuf_iterator { |
16181 | | using char_type = CharT; |
16182 | | using traits = Traits; |
16183 | | using difference_type = std::ptrdiff_t; |
16184 | | using streambuf_type = std::basic_streambuf<CharT, Traits>; |
16185 | | using ostream_type = std::basic_ostream<CharT, Traits>; |
16186 | | |
16187 | | constexpr ostreambuf_iterator() = default; |
16188 | | |
16189 | | ostreambuf_iterator(ostream_type& s) noexcept : sbuf_(s.rdbuf()) {} |
16190 | | |
16191 | | ostreambuf_iterator(streambuf_type* s) noexcept : sbuf_(s) {} |
16192 | | |
16193 | | ostreambuf_iterator& operator=(char_type c) |
16194 | | { |
16195 | | if (!failed()) { |
16196 | | failed_ = (sbuf_->sputc(c) == traits::eof()); |
16197 | | } |
16198 | | return *this; |
16199 | | } |
16200 | | |
16201 | | ostreambuf_iterator& operator*() |
16202 | | { |
16203 | | return *this; |
16204 | | } |
16205 | | ostreambuf_iterator& operator++() |
16206 | | { |
16207 | | return *this; |
16208 | | } |
16209 | | ostreambuf_iterator& operator++(int) |
16210 | | { |
16211 | | return *this; |
16212 | | } |
16213 | | |
16214 | | bool failed() const noexcept |
16215 | | { |
16216 | | return failed_; |
16217 | | } |
16218 | | |
16219 | | private: |
16220 | | streambuf_type* sbuf_ = nullptr; |
16221 | | bool failed_ = false; |
16222 | | }; |
16223 | | |
16224 | | NANO_END_NAMESPACE |
16225 | | |
16226 | | namespace std { |
16227 | | |
16228 | | template <typename C, typename T> |
16229 | | struct iterator_traits<::nano::ranges::ostreambuf_iterator<C, T>> { |
16230 | | using value_type = void; |
16231 | | using difference_type = ptrdiff_t; |
16232 | | using reference = void; |
16233 | | using pointer = void; |
16234 | | using iterator_category = output_iterator_tag; |
16235 | | }; |
16236 | | |
16237 | | } // namespace std |
16238 | | |
16239 | | #endif |
16240 | | |
16241 | | #endif |
16242 | | |
16243 | | // nanorange/memory.hpp |
16244 | | // |
16245 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16246 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16247 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16248 | | |
16249 | | #ifndef NANORANGE_MEMORY_HPP_INCLUDED |
16250 | | |
16251 | | // nanorange/memory/uninitialized_copy.hpp |
16252 | | // |
16253 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16254 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16255 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16256 | | |
16257 | | #ifndef NANORANGE_MEMORY_UNINITIALIZED_COPY_HPP_INCLUDED |
16258 | | #define NANORANGE_MEMORY_UNINITIALIZED_COPY_HPP_INCLUDED |
16259 | | |
16260 | | NANO_BEGIN_NAMESPACE |
16261 | | |
16262 | | template <typename I, typename O> |
16263 | | using uninitialized_copy_result = in_out_result<I, O>; |
16264 | | |
16265 | | namespace detail { |
16266 | | |
16267 | | struct uninitialized_copy_fn { |
16268 | | private: |
16269 | | friend struct uninitialized_copy_n_fn; |
16270 | | |
16271 | | template <typename I, typename S, typename O, typename S2> |
16272 | | static uninitialized_copy_result<I, O> impl4(I ifirst, |
16273 | | S ilast, |
16274 | | O ofirst, |
16275 | | S2 olast) |
16276 | | { |
16277 | | O oit = ofirst; |
16278 | | try { |
16279 | | for (; ifirst != ilast && oit != olast; ++ifirst, (void)++oit) { |
16280 | | ::new (detail::voidify(*oit)) |
16281 | | std::remove_reference_t<iter_reference_t<O>>(*ifirst); |
16282 | | } |
16283 | | return {std::move(ifirst), std::move(oit)}; |
16284 | | } |
16285 | | catch (...) { |
16286 | | nano::destroy(ofirst, ++oit); |
16287 | | throw; |
16288 | | } |
16289 | | } |
16290 | | |
16291 | | template <typename I, typename S, typename O> |
16292 | | static uninitialized_copy_result<I, O> impl3(I ifirst, |
16293 | | S ilast, |
16294 | | O ofirst) |
16295 | | { |
16296 | | O oit = ofirst; |
16297 | | try { |
16298 | | for (; ifirst != ilast; ++ifirst, (void)++oit) { |
16299 | | ::new (const_cast<void*>(static_cast<const volatile void*>( |
16300 | | std::addressof(*oit)))) |
16301 | | std::remove_reference_t<iter_reference_t<O>>(*ifirst); |
16302 | | } |
16303 | | return {std::move(ifirst), std::move(oit)}; |
16304 | | } |
16305 | | catch (...) { |
16306 | | nano::destroy(ofirst, ++oit); |
16307 | | throw; |
16308 | | } |
16309 | | } |
16310 | | |
16311 | | public: |
16312 | | // Four-legged |
16313 | | template <typename I, typename S, typename O, typename S2> |
16314 | | std::enable_if_t< |
16315 | | input_iterator<I> && sentinel_for<S, I> && |
16316 | | no_throw_forward_iterator<O> && no_throw_sentinel<S2, O> && |
16317 | | constructible_from<iter_value_t<O>, iter_reference_t<I>>, |
16318 | | uninitialized_copy_result<I, O>> |
16319 | | operator()(I ifirst, S ilast, O ofirst, S2 olast) const |
16320 | | { |
16321 | | return uninitialized_copy_fn::impl4( |
16322 | | std::move(ifirst), std::move(ilast), std::move(ofirst), |
16323 | | std::move(olast)); |
16324 | | } |
16325 | | |
16326 | | // Two ranges |
16327 | | template <typename IRng, typename ORng> |
16328 | | std::enable_if_t< |
16329 | | input_range<IRng> && no_throw_forward_range<ORng> && |
16330 | | constructible_from<iter_value_t<iterator_t<ORng>>, |
16331 | | iter_reference_t<iterator_t<IRng>>>, |
16332 | | uninitialized_copy_result<borrowed_iterator_t<IRng>, |
16333 | | borrowed_iterator_t<ORng>>> |
16334 | | operator()(IRng&& irng, ORng&& orng) const |
16335 | | { |
16336 | | return uninitialized_copy_fn::impl4( |
16337 | | nano::begin(irng), nano::end(irng), nano::begin(orng), |
16338 | | nano::end(orng)); |
16339 | | } |
16340 | | |
16341 | | // Three-legged |
16342 | | template <typename I, typename S, typename O> |
16343 | | NANO_DEPRECATED std::enable_if_t< |
16344 | | input_iterator<I> && sentinel_for<S, I> && |
16345 | | no_throw_forward_iterator<O> && |
16346 | | constructible_from<iter_value_t<O>, iter_reference_t<I>>, |
16347 | | uninitialized_copy_result<I, O>> |
16348 | | operator()(I ifirst, S ilast, O ofirst) const |
16349 | | { |
16350 | | return uninitialized_copy_fn::impl3( |
16351 | | std::move(ifirst), std::move(ilast), std::move(ofirst)); |
16352 | | } |
16353 | | |
16354 | | // Range and a half |
16355 | | template <typename IRng, typename O> |
16356 | | NANO_DEPRECATED std::enable_if_t< |
16357 | | input_range<IRng> && no_throw_forward_iterator<std::decay_t<O>> && |
16358 | | !no_throw_forward_range<O> && |
16359 | | constructible_from<iter_value_t<std::decay_t<O>>, |
16360 | | iter_reference_t<iterator_t<IRng>>>, |
16361 | | uninitialized_copy_result<borrowed_iterator_t<IRng>, |
16362 | | std::decay_t<O>>> |
16363 | | operator()(IRng&& irng, O&& ofirst) const |
16364 | | { |
16365 | | return uninitialized_copy_fn::impl3( |
16366 | | nano::begin(irng), nano::end(irng), std::forward<O>(ofirst)); |
16367 | | } |
16368 | | }; |
16369 | | |
16370 | | } // namespace detail |
16371 | | |
16372 | | NANO_INLINE_VAR(detail::uninitialized_copy_fn, uninitialized_copy) |
16373 | | |
16374 | | template <typename I, typename O> |
16375 | | using uninitialized_copy_n_result = in_out_result<I, O>; |
16376 | | |
16377 | | namespace detail { |
16378 | | |
16379 | | struct uninitialized_copy_n_fn { |
16380 | | template <typename I, typename O, typename S> |
16381 | | std::enable_if_t< |
16382 | | input_iterator<I> && no_throw_forward_iterator<O> && |
16383 | | no_throw_sentinel<S, O> && |
16384 | | constructible_from<iter_value_t<O>, iter_reference_t<I>>, |
16385 | | uninitialized_copy_n_result<I, O>> |
16386 | | operator()(I ifirst, iter_difference_t<I> n, O ofirst, S olast) const |
16387 | | { |
16388 | | auto t = uninitialized_copy_fn::impl4( |
16389 | | make_counted_iterator(std::move(ifirst), n), default_sentinel, |
16390 | | std::move(ofirst), std::move(olast)); |
16391 | | return {std::move(t).in.base(), std::move(t).out}; |
16392 | | } |
16393 | | |
16394 | | template <typename I, typename O> |
16395 | | NANO_DEPRECATED std::enable_if_t< |
16396 | | input_iterator<I> && no_throw_forward_iterator<O> && |
16397 | | constructible_from<iter_value_t<O>, iter_reference_t<I>>, |
16398 | | uninitialized_copy_n_result<I, O>> |
16399 | | operator()(I ifirst, iter_difference_t<I> n, O ofirst) const |
16400 | | { |
16401 | | auto t = uninitialized_copy_fn::impl3( |
16402 | | make_counted_iterator(std::move(ifirst), n), default_sentinel, |
16403 | | std::move(ofirst)); |
16404 | | return {std::move(t).in.base(), std::move(t).out}; |
16405 | | } |
16406 | | }; |
16407 | | |
16408 | | } // namespace detail |
16409 | | |
16410 | | NANO_INLINE_VAR(detail::uninitialized_copy_n_fn, uninitialized_copy_n) |
16411 | | |
16412 | | NANO_END_NAMESPACE |
16413 | | |
16414 | | #endif |
16415 | | |
16416 | | // nanorange/memory/uninitialized_default_construct.hpp |
16417 | | // |
16418 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16419 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16420 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16421 | | |
16422 | | #ifndef NANORANGE_MEMORY_UNINITIALIZED_DEFAULT_CONSTRUCT_HPP_INCLUDED |
16423 | | #define NANORANGE_MEMORY_UNINITIALIZED_DEFAULT_CONSTRUCT_HPP_INCLUDED |
16424 | | |
16425 | | NANO_BEGIN_NAMESPACE |
16426 | | |
16427 | | namespace detail { |
16428 | | |
16429 | | struct uninitialized_default_construct_fn { |
16430 | | private: |
16431 | | template <typename I, typename S> |
16432 | | static I impl(I first, S last) |
16433 | | { |
16434 | | I it = first; |
16435 | | try { |
16436 | | for (; it != last; ++it) { |
16437 | | ::new (detail::voidify(*it)) |
16438 | | std::remove_reference_t<iter_reference_t<I>>; |
16439 | | } |
16440 | | return it; |
16441 | | } |
16442 | | catch (...) { |
16443 | | nano::destroy(first, ++it); |
16444 | | throw; |
16445 | | } |
16446 | | } |
16447 | | |
16448 | | public: |
16449 | | template <typename I, typename S> |
16450 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16451 | | no_throw_sentinel<S, I> && |
16452 | | default_initializable<iter_value_t<I>>, |
16453 | | I> |
16454 | | operator()(I first, S last) const |
16455 | | { |
16456 | | return uninitialized_default_construct_fn::impl(std::move(first), |
16457 | | std::move(last)); |
16458 | | } |
16459 | | |
16460 | | template <typename Rng> |
16461 | | std::enable_if_t< |
16462 | | no_throw_forward_range<Rng> && |
16463 | | default_initializable<iter_value_t<iterator_t<Rng>>>, |
16464 | | borrowed_iterator_t<Rng>> |
16465 | | operator()(Rng&& rng) const |
16466 | | { |
16467 | | return uninitialized_default_construct_fn::impl(nano::begin(rng), |
16468 | | nano::end(rng)); |
16469 | | } |
16470 | | }; |
16471 | | |
16472 | | } // namespace detail |
16473 | | |
16474 | | NANO_INLINE_VAR(detail::uninitialized_default_construct_fn, |
16475 | | uninitialized_default_construct) |
16476 | | |
16477 | | namespace detail { |
16478 | | |
16479 | | struct uninitialized_default_construct_n_fn { |
16480 | | template <typename I> |
16481 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16482 | | default_initializable<iter_value_t<I>>, |
16483 | | I> |
16484 | | operator()(I first, iter_difference_t<I> n) const |
16485 | | { |
16486 | | return nano::uninitialized_default_construct( |
16487 | | make_counted_iterator(std::move(first), n), |
16488 | | default_sentinel) |
16489 | | .base(); |
16490 | | } |
16491 | | }; |
16492 | | |
16493 | | } // namespace detail |
16494 | | |
16495 | | NANO_INLINE_VAR(detail::uninitialized_default_construct_n_fn, |
16496 | | uninitialized_default_construct_n) |
16497 | | |
16498 | | NANO_END_NAMESPACE |
16499 | | |
16500 | | #endif |
16501 | | |
16502 | | // nanorange/memory/uninitialized_fill.hpp |
16503 | | // |
16504 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16505 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16506 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16507 | | |
16508 | | #ifndef NANORANGE_MEMORY_UNINITIALIZED_FILL_HPP_INCLUDED |
16509 | | #define NANORANGE_MEMORY_UNINITIALIZED_FILL_HPP_INCLUDED |
16510 | | |
16511 | | NANO_BEGIN_NAMESPACE |
16512 | | |
16513 | | namespace detail { |
16514 | | |
16515 | | struct uninitialized_fill_fn { |
16516 | | private: |
16517 | | friend struct uninitialized_fill_n_fn; |
16518 | | |
16519 | | template <typename I, typename S, typename T> |
16520 | | static I impl(I first, S last, const T& x) |
16521 | | { |
16522 | | I it = first; |
16523 | | try { |
16524 | | for (; it != last; ++it) { |
16525 | | ::new (detail::voidify(*it)) |
16526 | | std::remove_reference_t<iter_reference_t<I>>(x); |
16527 | | } |
16528 | | return it; |
16529 | | } |
16530 | | catch (...) { |
16531 | | nano::destroy(first, ++it); |
16532 | | throw; |
16533 | | } |
16534 | | } |
16535 | | |
16536 | | public: |
16537 | | template <typename I, typename S, typename T> |
16538 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16539 | | no_throw_sentinel<S, I> && |
16540 | | constructible_from<iter_value_t<I>, const T&>, |
16541 | | I> |
16542 | | operator()(I first, S last, const T& x) const |
16543 | | { |
16544 | | return uninitialized_fill_fn::impl(std::move(first), |
16545 | | std::move(last), x); |
16546 | | } |
16547 | | |
16548 | | template <typename Rng, typename T> |
16549 | | std::enable_if_t< |
16550 | | no_throw_forward_range<Rng> && |
16551 | | constructible_from<iter_value_t<iterator_t<Rng>>, const T&>, |
16552 | | borrowed_iterator_t<Rng>> |
16553 | | operator()(Rng&& rng, const T& x) const |
16554 | | { |
16555 | | return uninitialized_fill_fn::impl(nano::begin(rng), nano::end(rng), |
16556 | | x); |
16557 | | } |
16558 | | }; |
16559 | | |
16560 | | } // namespace detail |
16561 | | |
16562 | | NANO_INLINE_VAR(detail::uninitialized_fill_fn, uninitialized_fill) |
16563 | | |
16564 | | namespace detail { |
16565 | | |
16566 | | struct uninitialized_fill_n_fn { |
16567 | | template <typename I, typename T> |
16568 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16569 | | constructible_from<iter_value_t<I>, const T&>, |
16570 | | I> |
16571 | | operator()(I first, iter_difference_t<I> n, const T& x) const |
16572 | | { |
16573 | | return uninitialized_fill_fn::impl( |
16574 | | make_counted_iterator(std::move(first), n), |
16575 | | default_sentinel, x) |
16576 | | .base(); |
16577 | | } |
16578 | | }; |
16579 | | |
16580 | | } // namespace detail |
16581 | | |
16582 | | NANO_INLINE_VAR(detail::uninitialized_fill_n_fn, uninitialized_fill_n) |
16583 | | |
16584 | | NANO_END_NAMESPACE |
16585 | | |
16586 | | #endif |
16587 | | |
16588 | | // nanorange/memory/uninitialized_move.hpp |
16589 | | // |
16590 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16591 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16592 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16593 | | |
16594 | | #ifndef NANORANGE_MEMORY_UNINITIALIZED_MOVE_HPP_INCLUDED |
16595 | | #define NANORANGE_MEMORY_UNINITIALIZED_MOVE_HPP_INCLUDED |
16596 | | |
16597 | | NANO_BEGIN_NAMESPACE |
16598 | | |
16599 | | template <typename I, typename O> |
16600 | | using uninitialized_move_result = in_out_result<I, O>; |
16601 | | |
16602 | | namespace detail { |
16603 | | |
16604 | | struct uninitialized_move_fn { |
16605 | | private: |
16606 | | friend struct uninitialized_move_n_fn; |
16607 | | |
16608 | | template <typename I, typename S, typename O, typename S2> |
16609 | | static uninitialized_move_result<I, O> impl4(I ifirst, |
16610 | | S ilast, |
16611 | | O ofirst, |
16612 | | S2 olast) |
16613 | | { |
16614 | | O oit = ofirst; |
16615 | | try { |
16616 | | for (; ifirst != ilast && oit != olast; ++ifirst, (void)++oit) { |
16617 | | ::new (detail::voidify(*oit)) |
16618 | | std::remove_reference_t<iter_reference_t<O>>( |
16619 | | nano::iter_move(ifirst)); |
16620 | | } |
16621 | | return {std::move(ifirst), std::move(oit)}; |
16622 | | } |
16623 | | catch (...) { |
16624 | | nano::destroy(ofirst, ++oit); |
16625 | | throw; |
16626 | | } |
16627 | | } |
16628 | | |
16629 | | template <typename I, typename S, typename O> |
16630 | | static uninitialized_move_result<I, O> impl3(I ifirst, |
16631 | | S ilast, |
16632 | | O ofirst) |
16633 | | { |
16634 | | O oit = ofirst; |
16635 | | try { |
16636 | | for (; ifirst != ilast; ++ifirst, (void)++oit) { |
16637 | | ::new (detail::voidify(*oit)) |
16638 | | std::remove_reference_t<iter_reference_t<O>>( |
16639 | | nano::iter_move(ifirst)); |
16640 | | } |
16641 | | return {std::move(ifirst), std::move(oit)}; |
16642 | | } |
16643 | | catch (...) { |
16644 | | nano::destroy(ofirst, ++oit); |
16645 | | throw; |
16646 | | } |
16647 | | } |
16648 | | |
16649 | | public: |
16650 | | // Four-legged |
16651 | | template <typename I, typename S, typename O, typename S2> |
16652 | | std::enable_if_t< |
16653 | | input_iterator<I> && sentinel_for<S, I> && |
16654 | | no_throw_forward_iterator<O> && no_throw_sentinel<S2, O> && |
16655 | | constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>, |
16656 | | uninitialized_move_result<I, O>> |
16657 | | operator()(I ifirst, S ilast, O ofirst, S2 olast) const |
16658 | | { |
16659 | | return uninitialized_move_fn::impl4( |
16660 | | std::move(ifirst), std::move(ilast), std::move(ofirst), |
16661 | | std::move(olast)); |
16662 | | } |
16663 | | |
16664 | | // Two ranges |
16665 | | template <typename IRng, typename ORng> |
16666 | | std::enable_if_t< |
16667 | | input_range<IRng> && no_throw_forward_range<ORng> && |
16668 | | constructible_from<iter_value_t<iterator_t<ORng>>, |
16669 | | iter_rvalue_reference_t<iterator_t<IRng>>>, |
16670 | | uninitialized_move_result<borrowed_iterator_t<IRng>, |
16671 | | borrowed_iterator_t<ORng>>> |
16672 | | operator()(IRng&& irng, ORng&& orng) const |
16673 | | { |
16674 | | return uninitialized_move_fn::impl4( |
16675 | | nano::begin(irng), nano::end(irng), nano::begin(orng), |
16676 | | nano::end(orng)); |
16677 | | } |
16678 | | |
16679 | | // Three-legged |
16680 | | template <typename I, typename S, typename O> |
16681 | | NANO_DEPRECATED std::enable_if_t< |
16682 | | input_iterator<I> && sentinel_for<S, I> && |
16683 | | no_throw_forward_iterator<O> && |
16684 | | constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>, |
16685 | | uninitialized_move_result<I, O>> |
16686 | | operator()(I ifirst, S ilast, O ofirst) const |
16687 | | { |
16688 | | return uninitialized_move_fn::impl3( |
16689 | | std::move(ifirst), std::move(ilast), std::move(ofirst)); |
16690 | | } |
16691 | | |
16692 | | // Range and a half |
16693 | | template <typename IRng, typename O> |
16694 | | NANO_DEPRECATED std::enable_if_t< |
16695 | | input_range<IRng> && no_throw_forward_iterator<std::decay_t<O>> && |
16696 | | !no_throw_forward_range<O> && |
16697 | | constructible_from<iter_value_t<std::decay_t<O>>, |
16698 | | iter_rvalue_reference_t<iterator_t<IRng>>>, |
16699 | | uninitialized_move_result<borrowed_iterator_t<IRng>, |
16700 | | std::decay_t<O>>> |
16701 | | operator()(IRng&& irng, O&& ofirst) const |
16702 | | { |
16703 | | return uninitialized_move_fn::impl3( |
16704 | | nano::begin(irng), nano::end(irng), std::forward<O>(ofirst)); |
16705 | | } |
16706 | | }; |
16707 | | |
16708 | | } // namespace detail |
16709 | | |
16710 | | NANO_INLINE_VAR(detail::uninitialized_move_fn, uninitialized_move) |
16711 | | |
16712 | | template <typename I, typename O> |
16713 | | using uninitialized_move_n_result = in_out_result<I, O>; |
16714 | | |
16715 | | namespace detail { |
16716 | | |
16717 | | struct uninitialized_move_n_fn { |
16718 | | template <typename I, typename O, typename S> |
16719 | | std::enable_if_t< |
16720 | | input_iterator<I> && no_throw_forward_iterator<O> && |
16721 | | no_throw_sentinel<S, O> && |
16722 | | constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>, |
16723 | | uninitialized_move_n_result<I, O>> |
16724 | | operator()(I ifirst, iter_difference_t<I> n, O ofirst, S olast) const |
16725 | | { |
16726 | | auto t = uninitialized_move_fn::impl4( |
16727 | | make_counted_iterator(std::move(ifirst), n), default_sentinel, |
16728 | | std::move(ofirst), std::move(olast)); |
16729 | | return {std::move(t).in.base(), std::move(t).out}; |
16730 | | } |
16731 | | |
16732 | | template <typename I, typename O> |
16733 | | NANO_DEPRECATED std::enable_if_t< |
16734 | | input_iterator<I> && no_throw_forward_iterator<O> && |
16735 | | constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>, |
16736 | | uninitialized_move_n_result<I, O>> |
16737 | | operator()(I ifirst, iter_difference_t<I> n, O ofirst) const |
16738 | | { |
16739 | | auto t = uninitialized_move_fn::impl3( |
16740 | | make_counted_iterator(std::move(ifirst), n), default_sentinel, |
16741 | | std::move(ofirst)); |
16742 | | return {std::move(t).in.base(), std::move(t).out}; |
16743 | | } |
16744 | | }; |
16745 | | |
16746 | | } // namespace detail |
16747 | | |
16748 | | NANO_INLINE_VAR(detail::uninitialized_move_n_fn, uninitialized_move_n) |
16749 | | |
16750 | | NANO_END_NAMESPACE |
16751 | | |
16752 | | #endif |
16753 | | |
16754 | | // nanorange/memory/uninitialized_value_construct.hpp |
16755 | | // |
16756 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16757 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16758 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16759 | | |
16760 | | #ifndef NANORANGE_MEMORY_UNINITIALIZED_VALUE_CONSTRUCT_HPP_INCLUDED |
16761 | | #define NANORANGE_MEMORY_UNINITIALIZED_VALUE_CONSTRUCT_HPP_INCLUDED |
16762 | | |
16763 | | NANO_BEGIN_NAMESPACE |
16764 | | |
16765 | | namespace detail { |
16766 | | |
16767 | | struct uninitialized_value_construct_fn { |
16768 | | private: |
16769 | | template <typename I, typename S> |
16770 | | static I impl(I first, S last) |
16771 | | { |
16772 | | I it = first; |
16773 | | try { |
16774 | | for (; it != last; ++it) { |
16775 | | ::new (detail::voidify(*it)) |
16776 | | std::remove_reference_t<iter_reference_t<I>>(); |
16777 | | } |
16778 | | return it; |
16779 | | } |
16780 | | catch (...) { |
16781 | | nano::destroy(first, ++it); |
16782 | | throw; |
16783 | | } |
16784 | | } |
16785 | | |
16786 | | public: |
16787 | | template <typename I, typename S> |
16788 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16789 | | no_throw_sentinel<S, I> && |
16790 | | default_initializable<iter_value_t<I>>, |
16791 | | I> |
16792 | | operator()(I first, S last) const |
16793 | | { |
16794 | | return uninitialized_value_construct_fn::impl(std::move(first), |
16795 | | std::move(last)); |
16796 | | } |
16797 | | |
16798 | | template <typename Rng> |
16799 | | std::enable_if_t< |
16800 | | no_throw_forward_range<Rng> && |
16801 | | default_initializable<iter_value_t<iterator_t<Rng>>>, |
16802 | | borrowed_iterator_t<Rng>> |
16803 | | operator()(Rng&& rng) const |
16804 | | { |
16805 | | return uninitialized_value_construct_fn::impl(nano::begin(rng), |
16806 | | nano::end(rng)); |
16807 | | } |
16808 | | }; |
16809 | | |
16810 | | } // namespace detail |
16811 | | |
16812 | | NANO_INLINE_VAR(detail::uninitialized_value_construct_fn, |
16813 | | uninitialized_value_construct) |
16814 | | |
16815 | | namespace detail { |
16816 | | |
16817 | | struct uninitialized_value_construct_n_fn { |
16818 | | template <typename I> |
16819 | | std::enable_if_t<no_throw_forward_iterator<I> && |
16820 | | default_initializable<iter_value_t<I>>, |
16821 | | I> |
16822 | | operator()(I first, iter_difference_t<I> n) const |
16823 | | { |
16824 | | return nano::uninitialized_value_construct( |
16825 | | make_counted_iterator(std::move(first), n), |
16826 | | default_sentinel) |
16827 | | .base(); |
16828 | | } |
16829 | | }; |
16830 | | |
16831 | | } // namespace detail |
16832 | | |
16833 | | NANO_INLINE_VAR(detail::uninitialized_value_construct_n_fn, |
16834 | | uninitialized_value_construct_n) |
16835 | | |
16836 | | NANO_END_NAMESPACE |
16837 | | |
16838 | | #endif |
16839 | | |
16840 | | #endif |
16841 | | |
16842 | | // nanorange/utility.hpp |
16843 | | // |
16844 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16845 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16846 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16847 | | |
16848 | | #ifndef NANORANGE_UTILITY_HPP_INCLUDED |
16849 | | #define NANORANGE_UTILITY_HPP_INCLUDED |
16850 | | |
16851 | | #endif |
16852 | | |
16853 | | // nanorange/range.hpp |
16854 | | // |
16855 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16856 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16857 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16858 | | |
16859 | | #ifndef NANORANGE_VIEWS_HPP_INCLUDED |
16860 | | #define NANORANGE_VIEWS_HPP_INCLUDED |
16861 | | |
16862 | | // nanorange/views/all.hpp |
16863 | | // |
16864 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16865 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16866 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16867 | | |
16868 | | #ifndef NANORANGE_VIEWS_ALL_HPP_INCLUDED |
16869 | | #define NANORANGE_VIEWS_ALL_HPP_INCLUDED |
16870 | | |
16871 | | // nanorange/detail/views/range_adaptors.hpp |
16872 | | // |
16873 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
16874 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16875 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16876 | | |
16877 | | #ifndef NANORANGE_DETAIL_VIEW_RANGE_ADAPTORS_HPP_INCLUDED |
16878 | | #define NANORANGE_DETAIL_VIEW_RANGE_ADAPTORS_HPP_INCLUDED |
16879 | | |
16880 | | NANO_BEGIN_NAMESPACE |
16881 | | |
16882 | | namespace detail { |
16883 | | |
16884 | | template <typename> |
16885 | | inline constexpr bool is_raco = false; |
16886 | | |
16887 | | template <typename R, |
16888 | | typename C, |
16889 | | typename = std::enable_if_t<viewable_range<R> && |
16890 | | !is_raco<remove_cvref_t<R>> && |
16891 | | is_raco<remove_cvref_t<C>>>> |
16892 | | constexpr auto operator|(R&& lhs, C&& rhs) |
16893 | | -> decltype(std::forward<C>(rhs)(std::forward<R>(lhs))) |
16894 | | { |
16895 | | return std::forward<C>(rhs)(std::forward<R>(lhs)); |
16896 | | } |
16897 | | |
16898 | | template <typename LHS, typename RHS> |
16899 | | struct raco_pipe { |
16900 | | private: |
16901 | | LHS lhs_; |
16902 | | RHS rhs_; |
16903 | | |
16904 | | public: |
16905 | | constexpr raco_pipe(LHS&& lhs, RHS&& rhs) |
16906 | | : lhs_(std::move(lhs)), rhs_(std::move(rhs)) |
16907 | | { |
16908 | | } |
16909 | | |
16910 | | // FIXME: Do I need to do ref-qualified overloads of these too? |
16911 | | |
16912 | | template <typename R, std::enable_if_t<viewable_range<R>, int> = 0> |
16913 | | constexpr auto operator()(R&& r) |
16914 | | -> decltype(rhs_(lhs_(std::forward<R>(r)))) |
16915 | | { |
16916 | | return rhs_(lhs_(std::forward<R>(r))); |
16917 | | } |
16918 | | |
16919 | | template <typename R, std::enable_if_t<viewable_range<R>, int> = 0> |
16920 | | constexpr auto operator()(R&& r) const |
16921 | | -> decltype(rhs_(lhs_(std::forward<R>(r)))) |
16922 | | { |
16923 | | return rhs_(lhs_(std::forward<R>(r))); |
16924 | | } |
16925 | | }; |
16926 | | |
16927 | | template <typename LHS, typename RHS> |
16928 | | inline constexpr bool is_raco<raco_pipe<LHS, RHS>> = true; |
16929 | | |
16930 | | template <typename LHS, typename RHS> |
16931 | | constexpr auto operator|(LHS&& lhs, RHS&& rhs) |
16932 | | -> std::enable_if_t<is_raco<remove_cvref_t<LHS>> && |
16933 | | is_raco<remove_cvref_t<RHS>>, |
16934 | | raco_pipe<LHS, RHS>> |
16935 | | { |
16936 | | return raco_pipe<LHS, RHS>{std::forward<LHS>(lhs), |
16937 | | std::forward<RHS>(rhs)}; |
16938 | | } |
16939 | | |
16940 | | template <typename Lambda> |
16941 | | struct rao_proxy : Lambda { |
16942 | | constexpr explicit rao_proxy(Lambda&& l) : Lambda(std::move(l)) {} |
16943 | | }; |
16944 | | |
16945 | | template <typename L> |
16946 | | inline constexpr bool is_raco<rao_proxy<L>> = true; |
16947 | | |
16948 | | } // namespace detail |
16949 | | |
16950 | | NANO_END_NAMESPACE |
16951 | | |
16952 | | #endif |
16953 | | |
16954 | | // nanorange/detail/views/ref.hpp |
16955 | | // |
16956 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
16957 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
16958 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
16959 | | |
16960 | | #ifndef NANORANGE_VIEWS_REF_HPP_INCLUDED |
16961 | | #define NANORANGE_VIEWS_REF_HPP_INCLUDED |
16962 | | |
16963 | | NANO_BEGIN_NAMESPACE |
16964 | | |
16965 | | namespace ref_view_ { |
16966 | | |
16967 | | template <typename R> |
16968 | | class ref_view : public view_interface<ref_view<R>> { |
16969 | | static_assert(range<R> && std::is_object<R>::value, ""); |
16970 | | |
16971 | | R* r_ = nullptr; |
16972 | | |
16973 | | struct constructor_req { |
16974 | | static void FUN(R&); |
16975 | | static void FUN(R&&) = delete; |
16976 | | |
16977 | | template <typename T> |
16978 | | auto requires_() -> decltype(FUN(std::declval<T>())); |
16979 | | }; |
16980 | | |
16981 | | public: |
16982 | | constexpr ref_view() noexcept = default; |
16983 | | |
16984 | | template < |
16985 | | typename T, |
16986 | | std::enable_if_t<detail::not_same_as<T, ref_view>, int> = 0, |
16987 | | std::enable_if_t<detail::requires_<constructor_req, T>, int> = 0, |
16988 | | std::enable_if_t<convertible_to<T, R&>, int> = 0> |
16989 | | constexpr ref_view(T&& t) |
16990 | | : r_(std::addressof(static_cast<R&>(std::forward<T>(t)))) |
16991 | | { |
16992 | | } |
16993 | | |
16994 | | constexpr R& base() const |
16995 | | { |
16996 | | return *r_; |
16997 | | } |
16998 | | |
16999 | | constexpr iterator_t<R> begin() const |
17000 | | { |
17001 | | return ranges::begin(*r_); |
17002 | | } |
17003 | | |
17004 | | constexpr sentinel_t<R> end() const |
17005 | | { |
17006 | | return ranges::end(*r_); |
17007 | | } |
17008 | | |
17009 | | template <typename RR = R, |
17010 | | typename = decltype(ranges::empty(std::declval<RR&>()))> |
17011 | | constexpr bool empty() const |
17012 | | { |
17013 | | return ranges::empty(*r_); |
17014 | | } |
17015 | | |
17016 | | template <typename RR = R, std::enable_if_t<sized_range<RR>, int> = 0> |
17017 | | constexpr auto size() const |
17018 | | { |
17019 | | return ranges::size(*r_); |
17020 | | } |
17021 | | |
17022 | | template <typename RR = R, |
17023 | | std::enable_if_t<contiguous_range<RR>, int> = 0> |
17024 | | constexpr auto data() const |
17025 | | { |
17026 | | return ranges::data(*r_); |
17027 | | } |
17028 | | }; |
17029 | | |
17030 | | template <typename R, |
17031 | | std::enable_if_t<range<R> && std::is_object_v<R>, int> = 0> |
17032 | | ref_view(R&) -> ref_view<R>; |
17033 | | |
17034 | | } // namespace ref_view_ |
17035 | | |
17036 | | using ref_view_::ref_view; |
17037 | | |
17038 | | template <typename R> |
17039 | | inline constexpr bool enable_borrowed_range<ref_view<R>> = true; |
17040 | | |
17041 | | NANO_END_NAMESPACE |
17042 | | |
17043 | | #endif |
17044 | | |
17045 | | NANO_BEGIN_NAMESPACE |
17046 | | |
17047 | | namespace detail { |
17048 | | |
17049 | | struct all_view_fn { |
17050 | | private: |
17051 | | template <typename T> |
17052 | | static constexpr auto impl(T&& t, priority_tag<2>) noexcept( |
17053 | | noexcept(detail::decay_copy(std::forward<T>(t)))) |
17054 | | -> std::enable_if_t< |
17055 | | view<std::decay_t<T>>, |
17056 | | decltype(detail::decay_copy(std::forward<T>(t)))> |
17057 | | { |
17058 | | return std::forward<T>(t); |
17059 | | } |
17060 | | |
17061 | | template <typename T> |
17062 | | static constexpr auto impl(T&& t, priority_tag<1>) noexcept |
17063 | | -> decltype(ref_view(std::forward<T>(t))) |
17064 | | { |
17065 | | return ref_view(std::forward<T>(t)); |
17066 | | } |
17067 | | |
17068 | | template <typename T> |
17069 | | static constexpr auto impl(T&& t, priority_tag<0>) noexcept( |
17070 | | noexcept(nano::subrange{std::forward<T>(t)})) |
17071 | | -> decltype(nano::subrange{std::forward<T>(t)}) |
17072 | | { |
17073 | | return nano::subrange{std::forward<T>(t)}; |
17074 | | } |
17075 | | |
17076 | | public: |
17077 | | template <typename T> |
17078 | | constexpr auto operator()(T&& t) const |
17079 | | noexcept(noexcept(all_view_fn::impl(std::forward<T>(t), |
17080 | | priority_tag<2>{}))) |
17081 | | -> decltype(all_view_fn::impl(std::forward<T>(t), |
17082 | | priority_tag<2>{})) |
17083 | | { |
17084 | | return all_view_fn::impl(std::forward<T>(t), priority_tag<2>{}); |
17085 | | } |
17086 | | }; |
17087 | | |
17088 | | template <> |
17089 | | inline constexpr bool is_raco<all_view_fn> = true; |
17090 | | |
17091 | | } // namespace detail |
17092 | | |
17093 | | namespace views { |
17094 | | |
17095 | | NANO_INLINE_VAR(nano::detail::all_view_fn, all) |
17096 | | |
17097 | | } |
17098 | | |
17099 | | template <typename R> |
17100 | | using all_view = std::enable_if_t<viewable_range<R>, |
17101 | | decltype(views::all(std::declval<R>()))>; |
17102 | | |
17103 | | NANO_END_NAMESPACE |
17104 | | |
17105 | | #endif |
17106 | | |
17107 | | // nanorange/views/common.hpp |
17108 | | // |
17109 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
17110 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17111 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17112 | | |
17113 | | #ifndef NANORANGE_VIEWS_COMMON_HPP_INCLUDED |
17114 | | #define NANORANGE_VIEWS_COMMON_HPP_INCLUDED |
17115 | | |
17116 | | NANO_BEGIN_NAMESPACE |
17117 | | |
17118 | | template <typename V> |
17119 | | class common_view : public view_interface<common_view<V>> { |
17120 | | static_assert(view<V> && !common_range<V>, ""); |
17121 | | |
17122 | | template <typename VV> |
17123 | | using random_and_sized_t = |
17124 | | std::integral_constant<bool, |
17125 | | random_access_range<VV> && sized_range<VV>>; |
17126 | | |
17127 | | V base_ = V(); |
17128 | | |
17129 | | template <typename VV> |
17130 | | static constexpr auto do_begin(VV& base, std::true_type) |
17131 | | { |
17132 | | return ranges::begin(base); |
17133 | | } |
17134 | | |
17135 | | template <typename VV> |
17136 | | static constexpr auto do_begin(VV& base, std::false_type) |
17137 | | { |
17138 | | return common_iterator<iterator_t<VV>, sentinel_t<VV>>( |
17139 | | ranges::begin(base)); |
17140 | | } |
17141 | | |
17142 | | template <typename VV> |
17143 | | static constexpr auto do_end(VV& base, std::true_type) |
17144 | | { |
17145 | | return ranges::begin(base) + ranges::size(base); |
17146 | | } |
17147 | | |
17148 | | template <typename VV> |
17149 | | static constexpr auto do_end(VV& base, std::false_type) |
17150 | | { |
17151 | | return common_iterator<iterator_t<VV>, sentinel_t<VV>>( |
17152 | | ranges::end(base)); |
17153 | | } |
17154 | | |
17155 | | public: |
17156 | | common_view() = default; |
17157 | | |
17158 | | constexpr explicit common_view(V r) : base_(std::move(r)) {} |
17159 | | |
17160 | | template <typename R, |
17161 | | std::enable_if_t<detail::not_same_as<R, common_view>, int> = 0, |
17162 | | std::enable_if_t<viewable_range<R> && !common_range<R> && |
17163 | | constructible_from<V, all_view<R>>, |
17164 | | int> = 0> |
17165 | | constexpr explicit common_view(R&& r) |
17166 | | : base_(views::all(std::forward<R>(r))) |
17167 | | { |
17168 | | } |
17169 | | |
17170 | | constexpr V base() const |
17171 | | { |
17172 | | return base_; |
17173 | | } |
17174 | | |
17175 | | template <typename VV = V, std::enable_if_t<sized_range<VV>, int> = 0> |
17176 | | constexpr auto size() |
17177 | | { |
17178 | | return ranges::size(base_); |
17179 | | } |
17180 | | |
17181 | | template <typename VV = V, std::enable_if_t<sized_range<const VV>, int> = 0> |
17182 | | constexpr auto size() const |
17183 | | { |
17184 | | return ranges::size(base_); |
17185 | | } |
17186 | | |
17187 | | constexpr auto begin() |
17188 | | { |
17189 | | return do_begin<V>(base_, random_and_sized_t<V>{}); |
17190 | | } |
17191 | | |
17192 | | template <typename VV = V, std::enable_if_t<range<const VV>, int> = 0> |
17193 | | constexpr auto begin() const |
17194 | | { |
17195 | | return do_begin<const V>(base_, random_and_sized_t<const V>{}); |
17196 | | } |
17197 | | |
17198 | | constexpr auto end() |
17199 | | { |
17200 | | return do_end<V>(base_, random_and_sized_t<V>{}); |
17201 | | } |
17202 | | |
17203 | | template <typename VV = V, std::enable_if_t<range<const VV>, int> = 0> |
17204 | | constexpr auto end() const |
17205 | | { |
17206 | | return do_end<const V>(base_, random_and_sized_t<const V>{}); |
17207 | | } |
17208 | | }; |
17209 | | |
17210 | | template <typename R> |
17211 | | common_view(R&&) -> common_view<all_view<R>>; |
17212 | | |
17213 | | namespace detail { |
17214 | | |
17215 | | struct common_view_fn { |
17216 | | private: |
17217 | | template <typename T> |
17218 | | static constexpr auto |
17219 | | impl(T&& t, nano::detail::priority_tag<1>) noexcept( |
17220 | | noexcept(views::all(std::forward<T>(t)))) |
17221 | | -> std::enable_if_t<common_range<T>, |
17222 | | decltype(views::all(std::forward<T>(t)))> |
17223 | | { |
17224 | | return views::all(std::forward<T>(t)); |
17225 | | } |
17226 | | |
17227 | | template <typename T> |
17228 | | static constexpr auto impl(T&& t, nano::detail::priority_tag<0>) |
17229 | | -> common_view<all_view<T>> |
17230 | | { |
17231 | | return common_view<all_view<T>>{std::forward<T>(t)}; |
17232 | | } |
17233 | | |
17234 | | public: |
17235 | | template <typename T> |
17236 | | constexpr auto operator()(T&& t) const -> std::enable_if_t< |
17237 | | viewable_range<T>, |
17238 | | decltype(common_view_fn::impl(std::forward<T>(t), |
17239 | | nano::detail::priority_tag<1>{}))> |
17240 | | { |
17241 | | return common_view_fn::impl(std::forward<T>(t), |
17242 | | nano::detail::priority_tag<1>{}); |
17243 | | } |
17244 | | }; |
17245 | | |
17246 | | template <> |
17247 | | inline constexpr bool is_raco<common_view_fn> = true; |
17248 | | |
17249 | | } // namespace detail |
17250 | | |
17251 | | namespace views { |
17252 | | |
17253 | | NANO_INLINE_VAR(::nano::detail::common_view_fn, common) |
17254 | | |
17255 | | } // namespace views |
17256 | | |
17257 | | NANO_END_NAMESPACE |
17258 | | |
17259 | | #endif |
17260 | | |
17261 | | // nanorange/views/counted.hpp |
17262 | | // |
17263 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
17264 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17265 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17266 | | |
17267 | | #ifndef NANORANGE_VIEWS_COUNTED_HPP_INCLUDED |
17268 | | #define NANORANGE_VIEWS_COUNTED_HPP_INCLUDED |
17269 | | |
17270 | | NANO_BEGIN_NAMESPACE |
17271 | | |
17272 | | namespace views { |
17273 | | |
17274 | | namespace detail { |
17275 | | |
17276 | | struct counted_fn { |
17277 | | private: |
17278 | | template <typename I> |
17279 | | static constexpr auto impl( |
17280 | | I i, |
17281 | | iter_difference_t<I> n, |
17282 | | nano::detail::priority_tag<1>) noexcept(noexcept(nano::subrange{ |
17283 | | i, i + n})) |
17284 | | -> std::enable_if_t<random_access_iterator<I>, |
17285 | | decltype(nano::subrange{i, i + n})> |
17286 | | { |
17287 | | return nano::subrange{i, i + n}; |
17288 | | } |
17289 | | |
17290 | | template <typename I> |
17291 | | static constexpr auto impl( |
17292 | | I i, |
17293 | | iter_difference_t<I> n, |
17294 | | nano::detail::priority_tag<0>) noexcept(noexcept(nano::subrange{ |
17295 | | nano::make_counted_iterator(std::move(i), n), |
17296 | | default_sentinel})) -> decltype(nano::subrange{ |
17297 | | nano::make_counted_iterator(std::move(i), n), default_sentinel}) |
17298 | | { |
17299 | | return nano::subrange{ |
17300 | | nano::make_counted_iterator(std::move(i), n), |
17301 | | default_sentinel}; |
17302 | | } |
17303 | | |
17304 | | public: |
17305 | | template <typename E, typename F, typename T = std::decay_t<E>> |
17306 | | constexpr auto operator()(E&& e, F&& f) const noexcept(noexcept( |
17307 | | impl(std::forward<E>(e), |
17308 | | static_cast<iter_difference_t<T>>(std::forward<F>(f)), |
17309 | | nano::detail::priority_tag<1>{}))) |
17310 | | -> std::enable_if_t< |
17311 | | input_or_output_iterator<T> && |
17312 | | convertible_to<F, iter_difference_t<T>>, |
17313 | | decltype(impl( |
17314 | | std::forward<E>(e), |
17315 | | static_cast<iter_difference_t<T>>(std::forward<F>(f)), |
17316 | | nano::detail::priority_tag<1>{}))> |
17317 | | { |
17318 | | return impl( |
17319 | | std::forward<E>(e), |
17320 | | static_cast<iter_difference_t<T>>(std::forward<F>(f)), |
17321 | | nano::detail::priority_tag<1>{}); |
17322 | | } |
17323 | | }; |
17324 | | |
17325 | | } // namespace detail |
17326 | | |
17327 | | NANO_INLINE_VAR(detail::counted_fn, counted) |
17328 | | |
17329 | | } // namespace views |
17330 | | |
17331 | | NANO_END_NAMESPACE |
17332 | | |
17333 | | #endif |
17334 | | |
17335 | | // nanorange/views/drop.hpp |
17336 | | // |
17337 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
17338 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17339 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17340 | | |
17341 | | #ifndef NANORANGE_VIEWS_DROP_HPP_INCLUDED |
17342 | | #define NANORANGE_VIEWS_DROP_HPP_INCLUDED |
17343 | | |
17344 | | #include <optional> |
17345 | | |
17346 | | NANO_BEGIN_NAMESPACE |
17347 | | |
17348 | | namespace detail { |
17349 | | |
17350 | | template <bool IsRandomAccess, typename> |
17351 | | struct drop_view_cache {}; |
17352 | | |
17353 | | template <typename I> |
17354 | | struct drop_view_cache<false, I> { |
17355 | | std::optional<I> cached{}; |
17356 | | }; |
17357 | | |
17358 | | } // namespace detail |
17359 | | |
17360 | | template <typename R> |
17361 | | struct drop_view |
17362 | | : view_interface<drop_view<R>>, |
17363 | | private detail::drop_view_cache<random_access_range<R>, iterator_t<R>> { |
17364 | | static_assert(view<R>); |
17365 | | |
17366 | | drop_view() = default; |
17367 | | |
17368 | | constexpr drop_view(R base, range_difference_t<R> count) |
17369 | | : base_(std::move(base)), count_(count) |
17370 | | { |
17371 | | } |
17372 | | |
17373 | | constexpr R base() const |
17374 | | { |
17375 | | return base_; |
17376 | | } |
17377 | | |
17378 | | template < |
17379 | | typename RR = R, |
17380 | | std::enable_if_t<!(detail::simple_view<RR> && random_access_range<RR>), |
17381 | | int> = 0> |
17382 | | constexpr auto begin() |
17383 | | { |
17384 | | if constexpr (random_access_range<R>) { |
17385 | | return ranges::next(ranges::begin(base_), count_, |
17386 | | ranges::end(base_)); |
17387 | | } |
17388 | | else { |
17389 | | auto& c = this->cached; |
17390 | | if (!c.has_value()) { |
17391 | | c = ranges::next(ranges::begin(base_), count_, |
17392 | | ranges::end(base_)); |
17393 | | } |
17394 | | return *c; |
17395 | | } |
17396 | | } |
17397 | | |
17398 | | template <typename RR = R, |
17399 | | std::enable_if_t<random_access_range<const RR>, int> = 0> |
17400 | | constexpr auto begin() const |
17401 | | { |
17402 | | return ranges::next(ranges::begin(base_), count_, ranges::end(base_)); |
17403 | | } |
17404 | | |
17405 | | template <typename RR = R, |
17406 | | std::enable_if_t<!detail::simple_view<RR>, int> = 0> |
17407 | | constexpr auto end() |
17408 | | { |
17409 | | return ranges::end(base_); |
17410 | | } |
17411 | | |
17412 | | template <typename RR = R, std::enable_if_t<range<const RR>, int> = 0> |
17413 | | constexpr auto end() |
17414 | | { |
17415 | | return ranges::end(base_); |
17416 | | } |
17417 | | |
17418 | | template <typename RR = R, std::enable_if_t<sized_range<RR>, int> = 0> |
17419 | | constexpr auto size() |
17420 | | { |
17421 | | const auto s = ranges::size(base_); |
17422 | | const auto c = static_cast<decltype(s)>(count_); |
17423 | | return s < c ? 0 : s - c; |
17424 | | } |
17425 | | |
17426 | | template <typename RR = R, std::enable_if_t<sized_range<const RR>, int> = 0> |
17427 | | constexpr auto size() const |
17428 | | { |
17429 | | const auto s = ranges::size(base_); |
17430 | | const auto c = static_cast<decltype(s)>(count_); |
17431 | | return s < c ? 0 : s - c; |
17432 | | } |
17433 | | |
17434 | | private: |
17435 | | R base_ = R(); |
17436 | | range_difference_t<R> count_ = 0; |
17437 | | }; |
17438 | | |
17439 | | template <typename R> |
17440 | | drop_view(R&&, range_difference_t<R>) -> drop_view<all_view<R>>; |
17441 | | |
17442 | | namespace detail { |
17443 | | |
17444 | | struct drop_view_fn { |
17445 | | template <typename E, typename F> |
17446 | | constexpr auto operator()(E&& e, F&& f) const |
17447 | | -> decltype(drop_view{std::forward<E>(e), std::forward<F>(f)}) |
17448 | | { |
17449 | | return drop_view{std::forward<E>(e), std::forward<F>(f)}; |
17450 | | } |
17451 | | |
17452 | | template <typename C> |
17453 | | constexpr auto operator()(C c) const |
17454 | | { |
17455 | | return detail::rao_proxy{ |
17456 | | [c = std::move(c)](auto&& r) mutable |
17457 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
17458 | | -> decltype(drop_view{std::forward<decltype(r)>(r), |
17459 | | std::declval<C&&>()}) |
17460 | | #endif |
17461 | | { |
17462 | | return drop_view{std::forward<decltype(r)>(r), |
17463 | | std::move(c)}; |
17464 | | }}; |
17465 | | } |
17466 | | }; |
17467 | | |
17468 | | } // namespace detail |
17469 | | |
17470 | | namespace views { |
17471 | | |
17472 | | NANO_INLINE_VAR(nano::detail::drop_view_fn, drop) |
17473 | | |
17474 | | } |
17475 | | |
17476 | | NANO_END_NAMESPACE |
17477 | | |
17478 | | #endif |
17479 | | |
17480 | | // nanorange/views/drop_while.hpp |
17481 | | // |
17482 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
17483 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17484 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17485 | | |
17486 | | #ifndef NANORANGE_VIEWS_DROP_WHILE_HPP_INCLUDED |
17487 | | #define NANORANGE_VIEWS_DROP_WHILE_HPP_INCLUDED |
17488 | | |
17489 | | // nanorange/detail/views/semiregular_box.hpp |
17490 | | // |
17491 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
17492 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17493 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17494 | | |
17495 | | #ifndef NANORANGE_DETAIL_VIEW_SEMIREGULAR_BOX_HPP_INCLUDED |
17496 | | #define NANORANGE_DETAIL_VIEW_SEMIREGULAR_BOX_HPP_INCLUDED |
17497 | | |
17498 | | #include <optional> |
17499 | | |
17500 | | NANO_BEGIN_NAMESPACE |
17501 | | |
17502 | | namespace detail { |
17503 | | |
17504 | | template <typename T> |
17505 | | struct semiregular_box : std::optional<T> { |
17506 | | static_assert(copy_constructible<T>); |
17507 | | static_assert(std::is_object_v<T>); |
17508 | | |
17509 | | private: |
17510 | | std::optional<T>& base() |
17511 | | { |
17512 | | return *this; |
17513 | | } |
17514 | | std::optional<T> const& base() const |
17515 | | { |
17516 | | return *this; |
17517 | | } |
17518 | | |
17519 | | public: |
17520 | | template <typename U = T, |
17521 | | std::enable_if_t<default_initializable<U>, int> = 0> |
17522 | | constexpr semiregular_box() noexcept( |
17523 | | std::is_nothrow_default_constructible_v<T>) |
17524 | | : semiregular_box{std::in_place} |
17525 | | { |
17526 | | } |
17527 | | |
17528 | | template <typename U = T, |
17529 | | std::enable_if_t<!default_initializable<U>, int> = 0> |
17530 | | constexpr semiregular_box() |
17531 | | { |
17532 | | } |
17533 | | |
17534 | | // All other constructors get forwarded to optional -- but don't hijack |
17535 | | // copy/move construct |
17536 | | template <typename Arg0, |
17537 | | typename... Args, |
17538 | | std::enable_if_t< |
17539 | | constructible_from<std::optional<T>, Arg0, Args...> && |
17540 | | !same_as<remove_cvref_t<Arg0>, semiregular_box>, |
17541 | | int> = 0> |
17542 | | constexpr semiregular_box(Arg0&& arg0, Args&&... args) |
17543 | | : std::optional<T>{std::forward<Arg0>(arg0), |
17544 | | std::forward<Args>(args)...} |
17545 | | { |
17546 | | } |
17547 | | |
17548 | | constexpr semiregular_box(const semiregular_box&) = default; |
17549 | | constexpr semiregular_box(semiregular_box&&) = default; |
17550 | | |
17551 | | semiregular_box& operator=(const semiregular_box& other) |
17552 | | { |
17553 | | if constexpr (assignable_from<T&, const T&>) { |
17554 | | base() = other.base(); |
17555 | | } |
17556 | | else { |
17557 | | if (other) { |
17558 | | this->emplace(*other); |
17559 | | } |
17560 | | else { |
17561 | | this->reset(); |
17562 | | } |
17563 | | } |
17564 | | |
17565 | | return *this; |
17566 | | } |
17567 | | |
17568 | | semiregular_box& operator=(semiregular_box&& other) noexcept |
17569 | | { |
17570 | | if constexpr (assignable_from<T&, T>) { |
17571 | | base() = std::move(other.base()); |
17572 | | } |
17573 | | else { |
17574 | | if (other) { |
17575 | | this->emplace(std::move(*other)); |
17576 | | } |
17577 | | else { |
17578 | | this->reset(); |
17579 | | } |
17580 | | } |
17581 | | |
17582 | | return *this; |
17583 | | } |
17584 | | }; |
17585 | | |
17586 | | } // namespace detail |
17587 | | |
17588 | | NANO_END_NAMESPACE |
17589 | | |
17590 | | #endif |
17591 | | |
17592 | | NANO_BEGIN_NAMESPACE |
17593 | | |
17594 | | template <typename R, typename Pred> |
17595 | | struct drop_while_view : view_interface<drop_while_view<R, Pred>> { |
17596 | | static_assert(view<R>); |
17597 | | static_assert(input_range<R>); |
17598 | | static_assert(std::is_object_v<Pred>); |
17599 | | static_assert(indirect_unary_predicate<const Pred, iterator_t<R>>); |
17600 | | |
17601 | | drop_while_view() = default; |
17602 | | |
17603 | | constexpr drop_while_view(R base, Pred pred) |
17604 | | : base_(std::move(base)), pred_(std::move(pred)) |
17605 | | { |
17606 | | } |
17607 | | |
17608 | | constexpr R base() const |
17609 | | { |
17610 | | return base_; |
17611 | | } |
17612 | | |
17613 | | constexpr const Pred& pred() const |
17614 | | { |
17615 | | return *pred_; |
17616 | | } |
17617 | | |
17618 | | constexpr auto begin() |
17619 | | { |
17620 | | if (!cached_.has_value()) { |
17621 | | cached_ = ranges::find_if(base_, [&p = pred()](auto&& arg) { |
17622 | | return !nano::invoke(p, std::forward<decltype(arg)>(arg)); |
17623 | | }); |
17624 | | } |
17625 | | |
17626 | | return *cached_; |
17627 | | } |
17628 | | |
17629 | | constexpr auto end() |
17630 | | { |
17631 | | return ranges::end(base_); |
17632 | | } |
17633 | | |
17634 | | private: |
17635 | | R base_; |
17636 | | detail::semiregular_box<Pred> pred_; |
17637 | | std::optional<iterator_t<R>> cached_; |
17638 | | }; |
17639 | | |
17640 | | template <typename R, typename Pred> |
17641 | | drop_while_view(R&& r, Pred pred) -> drop_while_view<all_view<R>, Pred>; |
17642 | | |
17643 | | namespace detail { |
17644 | | |
17645 | | struct drop_while_view_fn { |
17646 | | template <typename E, typename F> |
17647 | | constexpr auto operator()(E&& e, F&& f) const |
17648 | | -> decltype(drop_while_view{std::forward<E>(e), std::forward<F>(f)}) |
17649 | | { |
17650 | | return drop_while_view{std::forward<E>(e), std::forward<F>(f)}; |
17651 | | } |
17652 | | |
17653 | | template <typename Pred> |
17654 | | constexpr auto operator()(Pred&& pred) const |
17655 | | { |
17656 | | return detail::rao_proxy{ |
17657 | | [p = std::forward<Pred>(pred)](auto&& r) mutable |
17658 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
17659 | | -> decltype(drop_while_view{std::forward<decltype(r)>(r), |
17660 | | std::declval<Pred&&>()}) |
17661 | | #endif |
17662 | | { |
17663 | | return drop_while_view{std::forward<decltype(r)>(r), |
17664 | | std::move(p)}; |
17665 | | }}; |
17666 | | } |
17667 | | }; |
17668 | | |
17669 | | } // namespace detail |
17670 | | |
17671 | | namespace views { |
17672 | | |
17673 | | NANO_INLINE_VAR(nano::detail::drop_while_view_fn, drop_while) |
17674 | | |
17675 | | } |
17676 | | |
17677 | | NANO_END_NAMESPACE |
17678 | | |
17679 | | #endif |
17680 | | |
17681 | | // nanorange/views/elements.hpp |
17682 | | // |
17683 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
17684 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
17685 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
17686 | | |
17687 | | #ifndef NANORANGE_VIEWS_ELEMENTS_HPP_INCLUDED |
17688 | | #define NANORANGE_VIEWS_ELEMENTS_HPP_INCLUDED |
17689 | | |
17690 | | NANO_BEGIN_NAMESPACE |
17691 | | |
17692 | | namespace detail { |
17693 | | |
17694 | | struct has_tuple_element_concept { |
17695 | | template <typename T, |
17696 | | typename I, |
17697 | | std::size_t N = I::value, |
17698 | | typename = typename std::tuple_size<T>::type> |
17699 | | auto requires_(T t) |
17700 | | -> decltype(requires_expr<(N < std::tuple_size_v<T>)>{}, |
17701 | | std::declval<std::tuple_element_t<N, T>>(), |
17702 | | requires_expr< |
17703 | | convertible_to<decltype(std::get<N>(t)), |
17704 | | std::tuple_element_t<N, T>>>{}); |
17705 | | }; |
17706 | | |
17707 | | template <typename T, std::size_t N> |
17708 | | NANO_CONCEPT has_tuple_element = |
17709 | | detail::requires_<has_tuple_element_concept, |
17710 | | T, |
17711 | | std::integral_constant<std::size_t, N>>; |
17712 | | |
17713 | | } // namespace detail |
17714 | | |
17715 | | template <typename R, std::size_t N> |
17716 | | struct elements_view : view_interface<elements_view<R, N>> { |
17717 | | static_assert(input_range<R>); |
17718 | | static_assert(view<R>); |
17719 | | static_assert(detail::has_tuple_element<range_value_t<R>, N>); |
17720 | | static_assert( |
17721 | | detail::has_tuple_element<std::remove_reference_t<range_reference_t<R>>, |
17722 | | N>); |
17723 | | |
17724 | | elements_view() = default; |
17725 | | |
17726 | | constexpr explicit elements_view(R base) : base_(std::move(base)) {} |
17727 | | |
17728 | | template <typename RR = R, |
17729 | | std::enable_if_t<!detail::simple_view<RR>, int> = 0> |
17730 | | constexpr auto begin() |
17731 | | { |
17732 | | return iterator<false>(ranges::begin(base_)); |
17733 | | } |
17734 | | |
17735 | | template <typename RR = R, |
17736 | | std::enable_if_t<detail::simple_view<RR>, int> = 0> |
17737 | | constexpr auto begin() const |
17738 | | { |
17739 | | return iterator<true>(ranges::begin(base_)); |
17740 | | } |
17741 | | |
17742 | | template <typename RR = R, |
17743 | | std::enable_if_t<!detail::simple_view<RR>, int> = 0> |
17744 | | constexpr auto end() |
17745 | | { |
17746 | | return ranges::end(base_); |
17747 | | } |
17748 | | |
17749 | | template <typename RR = R, |
17750 | | std::enable_if_t<detail::simple_view<RR>, int> = 0> |
17751 | | constexpr auto end() const |
17752 | | { |
17753 | | return ranges::end(base_); |
17754 | | } |
17755 | | |
17756 | | template <typename RR = R, std::enable_if_t<sized_range<RR>, int> = 0> |
17757 | | constexpr auto size() |
17758 | | { |
17759 | | return ranges::size(base_); |
17760 | | } |
17761 | | |
17762 | | template <typename RR = R, std::enable_if_t<sized_range<const RR>, int> = 0> |
17763 | | constexpr auto size() const |
17764 | | { |
17765 | | return ranges::size(base_); |
17766 | | } |
17767 | | |
17768 | | private: |
17769 | | template <bool Const> |
17770 | | struct iterator { |
17771 | | private: |
17772 | | using base_t = detail::conditional_t<Const, const R, R>; |
17773 | | friend iterator<!Const>; |
17774 | | |
17775 | | iterator_t<base_t> current_; |
17776 | | |
17777 | | public: |
17778 | | using iterator_category = iterator_category_t<iterator_t<base_t>>; |
17779 | | using value_type = |
17780 | | remove_cvref_t<std::tuple_element_t<N, range_value_t<base_t>>>; |
17781 | | using difference_type = range_difference_t<base_t>; |
17782 | | |
17783 | | iterator() = default; |
17784 | | |
17785 | | constexpr explicit iterator(iterator_t<base_t> current) |
17786 | | : current_(std::move(current)) |
17787 | | { |
17788 | | } |
17789 | | |
17790 | | template < |
17791 | | typename I, |
17792 | | std::enable_if_t<same_as<I, iterator<!Const>>, int> = 0, |
17793 | | bool C = Const, |
17794 | | typename B = base_t, |
17795 | | std::enable_if_t<C && convertible_to<iterator_t<R>, iterator_t<B>>, |
17796 | | int> = 0> |
17797 | | constexpr iterator(I i) : current_(std::move(i.current_)) |
17798 | | { |
17799 | | } |
17800 | | |
17801 | | constexpr iterator_t<base_t> base() const |
17802 | | { |
17803 | | return current_; |
17804 | | } |
17805 | | |
17806 | | constexpr decltype(auto) operator*() const |
17807 | | { |
17808 | | return std::get<N>(*current_); |
17809 | | } |
17810 | | |
17811 | | constexpr iterator& operator++() |
17812 | | { |
17813 | | ++current_; |
17814 | | return *this; |
17815 | | } |
17816 | | |
17817 | | constexpr auto operator++(int) |
17818 | | { |
17819 | | if constexpr (forward_range<base_t>) { |
17820 | | auto temp = *this; |
17821 | | ++*this; |
17822 | | return temp; |
17823 | | } |
17824 | | else { |
17825 | | ++*this; |
17826 | | } |
17827 | | } |
17828 | | |
17829 | | template <typename B = base_t> |
17830 | | constexpr auto operator--() |
17831 | | -> std::enable_if_t<bidirectional_range<B>, iterator&> |
17832 | | { |
17833 | | --current_; |
17834 | | return *this; |
17835 | | } |
17836 | | |
17837 | | template <typename B = base_t> |
17838 | | constexpr auto operator--(int) |
17839 | | -> std::enable_if_t<bidirectional_range<B>, iterator> |
17840 | | { |
17841 | | auto temp = *this; |
17842 | | ++*this; |
17843 | | return temp; |
17844 | | } |
17845 | | |
17846 | | template <typename B = base_t> |
17847 | | constexpr auto operator+=(difference_type x) |
17848 | | -> std::enable_if_t<random_access_range<B>, iterator&> |
17849 | | { |
17850 | | current_ += x; |
17851 | | return *this; |
17852 | | } |
17853 | | |
17854 | | template <typename B = base_t> |
17855 | | constexpr auto operator-=(difference_type x) |
17856 | | -> std::enable_if_t<random_access_range<B>, iterator&> |
17857 | | { |
17858 | | current_ -= x; |
17859 | | return *this; |
17860 | | } |
17861 | | |
17862 | | template <typename B = base_t, |
17863 | | std::enable_if_t<random_access_range<B>, int> = 0> |
17864 | | constexpr decltype(auto) operator[](difference_type n) const |
17865 | | { |
17866 | | return std::get<N>(*(current_ + n)); |
17867 | | } |
17868 | | |
17869 | | template <typename B = base_t> |
17870 | | friend constexpr auto operator==(const iterator& x, const iterator& y) |
17871 | | -> std::enable_if_t<equality_comparable<iterator_t<B>>, bool> |
17872 | | { |
17873 | | return x.current_ == y.current_; |
17874 | | } |
17875 | | |
17876 | | template <typename B = base_t> |
17877 | | friend constexpr auto operator!=(const iterator& x, const iterator& y) |
17878 | | -> std::enable_if_t<equality_comparable<iterator_t<B>>, bool> |
17879 | | { |
17880 | | return !(x == y); |
17881 | | } |
17882 | | |
17883 | | // Make these friend functions templates to keep MSVC happy |
17884 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
17885 | | template <typename = void> |
17886 | | #endif |
17887 | | friend constexpr bool operator==(const iterator& x, |
17888 | | const sentinel_t<base_t>& y) |
17889 | | { |
17890 | | return x.current_ == y; |
17891 | | } |
17892 | | |
17893 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
17894 | | template <typename = void> |
17895 | | #endif |
17896 | | friend constexpr bool operator==(const sentinel_t<base_t>& y, |
17897 | | const iterator& x) |
17898 | | { |
17899 | | return x.current_ == y; |
17900 | | } |
17901 | | |
17902 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
17903 | | template <typename = void> |
17904 | | #endif |
17905 | | friend constexpr bool operator!=(const iterator& x, |
17906 | | const sentinel_t<base_t>& y) |
17907 | | { |
17908 | | return !(x == y); |
17909 | | } |
17910 | | |
17911 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
17912 | | template <typename = void> |
17913 | | #endif |
17914 | | friend constexpr bool operator!=(const sentinel_t<base_t>& y, |
17915 | | const iterator& x) |
17916 | | { |
17917 | | return !(x == y); |
17918 | | } |
17919 | | |
17920 | | template <typename B = base_t> |
17921 | | friend constexpr auto operator<(const iterator& x, const iterator& y) |
17922 | | -> std::enable_if_t<random_access_range<B>, bool> |
17923 | | { |
17924 | | return x.current_ < y.current_; |
17925 | | } |
17926 | | |
17927 | | template <typename B = base_t> |
17928 | | friend constexpr auto operator>(const iterator& x, const iterator& y) |
17929 | | -> std::enable_if_t<random_access_range<B>, bool> |
17930 | | { |
17931 | | return (y < x); |
17932 | | } |
17933 | | |
17934 | | template <typename B = base_t> |
17935 | | friend constexpr auto operator<=(const iterator& x, const iterator& y) |
17936 | | -> std::enable_if_t<random_access_range<B>, bool> |
17937 | | { |
17938 | | return !(y < x); |
17939 | | } |
17940 | | |
17941 | | template <typename B = base_t> |
17942 | | friend constexpr auto operator>=(const iterator& x, const iterator& y) |
17943 | | -> std::enable_if_t<random_access_range<B>, bool> |
17944 | | { |
17945 | | return !(x < y); |
17946 | | } |
17947 | | |
17948 | | template <typename B = base_t> |
17949 | | friend constexpr auto operator+(const iterator& x, difference_type y) |
17950 | | -> std::enable_if_t<random_access_range<B>, iterator> |
17951 | | { |
17952 | | return iterator{x} += y; |
17953 | | } |
17954 | | |
17955 | | template <typename B = base_t> |
17956 | | friend constexpr auto operator+(difference_type x, const iterator& y) |
17957 | | -> std::enable_if_t<random_access_range<B>, iterator> |
17958 | | { |
17959 | | return y + x; |
17960 | | } |
17961 | | |
17962 | | template <typename B = base_t> |
17963 | | friend constexpr auto operator-(const iterator& x, difference_type y) |
17964 | | -> std::enable_if_t<random_access_range<B>, iterator> |
17965 | | { |
17966 | | return iterator{x} -= y; |
17967 | | } |
17968 | | |
17969 | | template <typename B = base_t> |
17970 | | friend constexpr auto operator-(const iterator& x, const iterator& y) |
17971 | | -> std::enable_if_t<random_access_range<B>, difference_type> |
17972 | | { |
17973 | | return x.current_ - y.current_; |
17974 | | } |
17975 | | |
17976 | | template <typename B = base_t> |
17977 | | friend constexpr auto operator-(const iterator& x, |
17978 | | const sentinel_t<base_t>& y) |
17979 | | -> std::enable_if_t< |
17980 | | sized_sentinel_for<sentinel_t<B>, iterator_t<B>>, |
17981 | | difference_type> |
17982 | | { |
17983 | | return x.current_ - y; |
17984 | | } |
17985 | | |
17986 | | template <typename B = base_t> |
17987 | | friend constexpr auto operator-(const sentinel_t<base_t>& x, |
17988 | | const iterator& y) |
17989 | | -> std::enable_if_t< |
17990 | | sized_sentinel_for<sentinel_t<B>, iterator_t<B>>, |
17991 | | difference_type> |
17992 | | { |
17993 | | return -(y - x); |
17994 | | } |
17995 | | }; |
17996 | | |
17997 | | R base_ = R(); |
17998 | | }; |
17999 | | |
18000 | | template <typename R> |
18001 | | using keys_view = elements_view<all_view<R>, 0>; |
18002 | | |
18003 | | template <typename R> |
18004 | | using values_view = elements_view<all_view<R>, 1>; |
18005 | | |
18006 | | namespace detail { |
18007 | | |
18008 | | template <std::size_t N> |
18009 | | struct elements_view_fn { |
18010 | | template <typename E> |
18011 | | constexpr auto operator()(E&& e) const |
18012 | | -> decltype(elements_view<all_view<decltype(std::forward<E>(e))>, |
18013 | | N>{std::forward<E>(e)}) |
18014 | | { |
18015 | | return elements_view<all_view<decltype(std::forward<E>(e))>, N>{ |
18016 | | std::forward<E>(e)}; |
18017 | | } |
18018 | | }; |
18019 | | |
18020 | | template <std::size_t N> |
18021 | | inline constexpr bool is_raco<elements_view_fn<N>> = true; |
18022 | | |
18023 | | } // namespace detail |
18024 | | |
18025 | | namespace views { |
18026 | | |
18027 | | inline namespace function_objects { |
18028 | | |
18029 | | template <std::size_t N> |
18030 | | inline constexpr nano::detail::elements_view_fn<N> elements{}; |
18031 | | |
18032 | | inline constexpr nano::detail::elements_view_fn<0> keys{}; |
18033 | | |
18034 | | inline constexpr nano::detail::elements_view_fn<1> values{}; |
18035 | | |
18036 | | } // namespace function_objects |
18037 | | |
18038 | | } // namespace views |
18039 | | |
18040 | | NANO_END_NAMESPACE |
18041 | | |
18042 | | #endif |
18043 | | |
18044 | | // nanorange/views/empty.hpp |
18045 | | // |
18046 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
18047 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
18048 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
18049 | | |
18050 | | #ifndef NANORANGE_VIEWS_EMPTY_HPP_INCLUDED |
18051 | | #define NANORANGE_VIEWS_EMPTY_HPP_INCLUDED |
18052 | | |
18053 | | NANO_BEGIN_NAMESPACE |
18054 | | |
18055 | | namespace empty_view_ { |
18056 | | |
18057 | | template <typename T> |
18058 | | class empty_view : view_interface<empty_view<T>> { |
18059 | | static_assert(std::is_object<T>::value, ""); |
18060 | | |
18061 | | public: |
18062 | | static constexpr T* begin() noexcept |
18063 | | { |
18064 | | return nullptr; |
18065 | | } |
18066 | | static constexpr T* end() noexcept |
18067 | | { |
18068 | | return nullptr; |
18069 | | } |
18070 | | static constexpr std::ptrdiff_t size() noexcept |
18071 | | { |
18072 | | return 0; |
18073 | | } |
18074 | | static constexpr T* data() noexcept |
18075 | | { |
18076 | | return nullptr; |
18077 | | } |
18078 | | |
18079 | | static constexpr bool empty() noexcept |
18080 | | { |
18081 | | return true; |
18082 | | } |
18083 | | }; |
18084 | | |
18085 | | } // namespace empty_view_ |
18086 | | |
18087 | | using empty_view_::empty_view; |
18088 | | |
18089 | | template <typename T> |
18090 | | inline constexpr bool enable_borrowed_range<empty_view<T>> = true; |
18091 | | |
18092 | | namespace views { |
18093 | | |
18094 | | template <typename T, typename = std::enable_if_t<std::is_object<T>::value>> |
18095 | | inline constexpr empty_view<T> empty{}; |
18096 | | |
18097 | | } |
18098 | | |
18099 | | NANO_END_NAMESPACE |
18100 | | |
18101 | | #endif |
18102 | | |
18103 | | // nanorange/views/filter.hpp |
18104 | | // |
18105 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
18106 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
18107 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
18108 | | |
18109 | | #ifndef NANORANGE_VIEWS_FILTER_HPP_INCLUDED |
18110 | | #define NANORANGE_VIEWS_FILTER_HPP_INCLUDED |
18111 | | |
18112 | | #include <cassert> |
18113 | | |
18114 | | NANO_BEGIN_NAMESPACE |
18115 | | |
18116 | | namespace detail { |
18117 | | |
18118 | | template <typename V> |
18119 | | constexpr auto filter_view_iter_cat_helper() |
18120 | | { |
18121 | | using C = iterator_category_t<iterator_t<V>>; |
18122 | | if constexpr (derived_from<C, bidirectional_iterator_tag>) { |
18123 | | return bidirectional_iterator_tag{}; |
18124 | | } |
18125 | | else if constexpr (derived_from<C, forward_iterator_tag>) { |
18126 | | return forward_iterator_tag{}; |
18127 | | } |
18128 | | else { |
18129 | | return input_iterator_tag{}; |
18130 | | } |
18131 | | } |
18132 | | |
18133 | | constexpr inline auto as_ref = [](auto& pred) { |
18134 | | return [&p = pred](auto&& arg) { |
18135 | | return nano::invoke(p, std::forward<decltype(arg)>(arg)); |
18136 | | }; |
18137 | | }; |
18138 | | |
18139 | | } // namespace detail |
18140 | | |
18141 | | namespace filter_view_ { |
18142 | | |
18143 | | template <typename V, typename Pred> |
18144 | | struct filter_view : view_interface<filter_view<V, Pred>> { |
18145 | | // FIXME: GCC9 recursive constraint (?) problems again |
18146 | | // static_assert(input_range<V>); |
18147 | | static_assert(input_iterator<iterator_t<V>>); |
18148 | | static_assert(indirect_unary_predicate<Pred, iterator_t<V>>); |
18149 | | static_assert(view<V>); |
18150 | | static_assert(std::is_object_v<Pred>); |
18151 | | |
18152 | | private: |
18153 | | V base_ = V(); |
18154 | | detail::semiregular_box<Pred> pred_; |
18155 | | |
18156 | | struct iterator { |
18157 | | private: |
18158 | | iterator_t<V> current_ = iterator_t<V>(); |
18159 | | filter_view* parent_ = nullptr; |
18160 | | |
18161 | | public: |
18162 | | // using iterator_concept = ... |
18163 | | using iterator_category = |
18164 | | decltype(detail::filter_view_iter_cat_helper<V>()); |
18165 | | using value_type = iter_value_t<iterator_t<V>>; |
18166 | | using difference_type = iter_difference_t<iterator_t<V>>; |
18167 | | // Extension: legacy typedefs |
18168 | | using pointer = iterator_t<V>; |
18169 | | using reference = iter_reference_t<iterator_t<V>>; |
18170 | | |
18171 | | iterator() = default; |
18172 | | constexpr iterator(filter_view& parent, iterator_t<V> current) |
18173 | | : current_(std::move(current)), parent_(std::addressof(parent)) |
18174 | | { |
18175 | | } |
18176 | | |
18177 | | constexpr iterator_t<V> base() const |
18178 | | { |
18179 | | return current_; |
18180 | | } |
18181 | | |
18182 | | constexpr iter_reference_t<iterator_t<V>> operator*() const |
18183 | | { |
18184 | | return *current_; |
18185 | | } |
18186 | | |
18187 | | template <typename VV = V> |
18188 | | constexpr auto operator->() const |
18189 | | -> std::enable_if_t<detail::has_arrow<iterator_t<VV>>, |
18190 | | iterator_t<V>> |
18191 | | { |
18192 | | return current_; |
18193 | | } |
18194 | | |
18195 | | constexpr iterator& operator++() |
18196 | | { |
18197 | | current_ = |
18198 | | ranges::find_if(++current_, ranges::end(parent_->base_), |
18199 | | detail::as_ref(*parent_->pred_)); |
18200 | | return *this; |
18201 | | } |
18202 | | |
18203 | | constexpr auto operator++(int) |
18204 | | { |
18205 | | if constexpr (forward_range<V>) { |
18206 | | auto tmp = *this; |
18207 | | ++*this; |
18208 | | return tmp; |
18209 | | } |
18210 | | else { |
18211 | | ++*this; |
18212 | | } |
18213 | | } |
18214 | | |
18215 | | template <typename VV = V> |
18216 | | constexpr auto operator--() |
18217 | | -> std::enable_if_t<bidirectional_range<VV>, iterator&> |
18218 | | { |
18219 | | do { |
18220 | | --current_; |
18221 | | } while (!nano::invoke(*parent_->pred_, *current_)); |
18222 | | return *this; |
18223 | | } |
18224 | | |
18225 | | template <typename VV = V> |
18226 | | constexpr auto operator--(int) |
18227 | | -> std::enable_if_t<bidirectional_range<VV>, iterator> |
18228 | | { |
18229 | | auto tmp = *this; |
18230 | | --*this; |
18231 | | return tmp; |
18232 | | } |
18233 | | |
18234 | | template <typename VV = V> |
18235 | | friend constexpr auto operator==(const iterator& x, |
18236 | | const iterator& y) |
18237 | | -> std::enable_if_t<equality_comparable<iterator_t<VV>>, bool> |
18238 | | { |
18239 | | return x.current_ == y.current_; |
18240 | | } |
18241 | | |
18242 | | template <typename VV = V> |
18243 | | friend constexpr auto operator!=(const iterator& x, |
18244 | | const iterator& y) |
18245 | | -> std::enable_if_t<equality_comparable<iterator_t<VV>>, bool> |
18246 | | { |
18247 | | return !(x == y); |
18248 | | } |
18249 | | |
18250 | | friend constexpr iter_rvalue_reference_t<iterator_t<V>> |
18251 | | iter_move(const iterator& i) noexcept( |
18252 | | noexcept(ranges::iter_move(i.current_))) |
18253 | | { |
18254 | | return ranges::iter_move(i.current_); |
18255 | | } |
18256 | | |
18257 | | template <typename VV = V> |
18258 | | friend constexpr auto |
18259 | | iter_swap(const iterator& x, const iterator& y) noexcept( |
18260 | | noexcept(ranges::iter_swap(x.current_, y.current_))) |
18261 | | -> std::enable_if_t<indirectly_swappable<iterator_t<VV>>> |
18262 | | { |
18263 | | ranges::iter_swap(x.current_, y.current_); |
18264 | | } |
18265 | | }; |
18266 | | |
18267 | | struct sentinel { |
18268 | | private: |
18269 | | sentinel_t<V> end_ = sentinel_t<V>(); |
18270 | | |
18271 | | public: |
18272 | | sentinel() = default; |
18273 | | |
18274 | | constexpr explicit sentinel(filter_view& parent) |
18275 | | : end_(ranges::end(parent.base_)) |
18276 | | { |
18277 | | } |
18278 | | |
18279 | | constexpr sentinel_t<V> base() const |
18280 | | { |
18281 | | return end_; |
18282 | | } |
18283 | | |
18284 | | // Make these friend functions templates to keep MSVC happy |
18285 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
18286 | | template <typename = void> |
18287 | | #endif |
18288 | | friend constexpr bool operator==(const iterator& i, |
18289 | | const sentinel& s) |
18290 | | { |
18291 | | return i.base() == s.end_; |
18292 | | } |
18293 | | |
18294 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
18295 | | template <typename = void> |
18296 | | #endif |
18297 | | friend constexpr bool operator==(const sentinel& s, |
18298 | | const iterator& i) |
18299 | | { |
18300 | | return i == s; |
18301 | | } |
18302 | | |
18303 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
18304 | | template <typename = void> |
18305 | | #endif |
18306 | | friend constexpr bool operator!=(const iterator& i, |
18307 | | const sentinel& s) |
18308 | | { |
18309 | | return !(i == s); |
18310 | | } |
18311 | | |
18312 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
18313 | | template <typename = void> |
18314 | | #endif |
18315 | | friend constexpr bool operator!=(const sentinel& s, |
18316 | | const iterator& i) |
18317 | | { |
18318 | | return !(i == s); |
18319 | | } |
18320 | | }; |
18321 | | |
18322 | | std::optional<iterator> begin_cache_{}; |
18323 | | |
18324 | | public: |
18325 | | filter_view() = default; |
18326 | | |
18327 | | constexpr filter_view(V base, Pred pred) |
18328 | | : base_(std::move(base)), pred_(std::move(pred)) |
18329 | | { |
18330 | | } |
18331 | | |
18332 | | constexpr V base() const |
18333 | | { |
18334 | | return base_; |
18335 | | } |
18336 | | |
18337 | | constexpr iterator begin() |
18338 | | { |
18339 | | if (begin_cache_) { |
18340 | | return *begin_cache_; |
18341 | | } |
18342 | | |
18343 | | assert(pred_.has_value()); |
18344 | | begin_cache_ = std::optional<iterator>{ |
18345 | | iterator{*this, nano::find_if(base_, detail::as_ref(*pred_))}}; |
18346 | | return *begin_cache_; |
18347 | | } |
18348 | | |
18349 | | constexpr auto end() |
18350 | | { |
18351 | | if constexpr (common_range<V>) { |
18352 | | return iterator{*this, ranges::end(base_)}; |
18353 | | } |
18354 | | else { |
18355 | | return sentinel{*this}; |
18356 | | } |
18357 | | } |
18358 | | }; |
18359 | | |
18360 | | template <typename R, typename Pred> |
18361 | | filter_view(R&&, Pred) -> filter_view<all_view<R>, Pred>; |
18362 | | |
18363 | | } // namespace filter_view_ |
18364 | | |
18365 | | using filter_view_::filter_view; |
18366 | | |
18367 | | namespace detail { |
18368 | | |
18369 | | struct filter_view_fn { |
18370 | | template <typename Pred> |
18371 | | constexpr auto operator()(Pred pred) const |
18372 | | { |
18373 | | return detail::rao_proxy{ |
18374 | | [p = std::move(pred)](auto&& r) mutable |
18375 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
18376 | | -> decltype(filter_view{std::forward<decltype(r)>(r), |
18377 | | std::declval<Pred&&>()}) |
18378 | | #endif |
18379 | | { |
18380 | | return filter_view{std::forward<decltype(r)>(r), |
18381 | | std::move(p)}; |
18382 | | }}; |
18383 | | } |
18384 | | |
18385 | | template <typename R, typename Pred> |
18386 | | constexpr auto operator()(R&& r, Pred pred) const |
18387 | | noexcept(noexcept(filter_view{std::forward<R>(r), std::move(pred)})) |
18388 | | -> decltype(filter_view{std::forward<R>(r), std::move(pred)}) |
18389 | | { |
18390 | | return filter_view{std::forward<R>(r), std::move(pred)}; |
18391 | | } |
18392 | | }; |
18393 | | |
18394 | | } // namespace detail |
18395 | | |
18396 | | namespace views { |
18397 | | |
18398 | | NANO_INLINE_VAR(nano::detail::filter_view_fn, filter) |
18399 | | |
18400 | | } |
18401 | | |
18402 | | NANO_END_NAMESPACE |
18403 | | |
18404 | | #endif |
18405 | | |
18406 | | // nanorange/views/iota.hpp |
18407 | | // |
18408 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
18409 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
18410 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
18411 | | |
18412 | | #ifndef NANORANGE_VIEWS_IOTA_HPP_INCLUDED |
18413 | | #define NANORANGE_VIEWS_IOTA_HPP_INCLUDED |
18414 | | |
18415 | | NANO_BEGIN_NAMESPACE |
18416 | | |
18417 | | namespace detail { |
18418 | | |
18419 | | struct decrementable_concept { |
18420 | | template <typename I> |
18421 | | auto requires_(I i) |
18422 | | -> decltype(requires_expr<same_as<decltype(--i), I&>>{}, |
18423 | | requires_expr<same_as<decltype(i--), I>>{}); |
18424 | | }; |
18425 | | |
18426 | | template <typename I> |
18427 | | NANO_CONCEPT decrementable = |
18428 | | incrementable<I> && requires_<decrementable_concept, I>; |
18429 | | |
18430 | | template <typename W> |
18431 | | using iota_diff_t = iter_difference_t<W>; |
18432 | | |
18433 | | struct advanceable_concept { |
18434 | | template <typename I> |
18435 | | auto requires_(I i, const I j, const iota_diff_t<I> n) |
18436 | | -> decltype(requires_expr<same_as<decltype(i += n), I&>>{}, |
18437 | | requires_expr<same_as<decltype(i -= n), I&>>{}, |
18438 | | I(j + n), |
18439 | | I(n + j), |
18440 | | I(j - n), |
18441 | | requires_expr< |
18442 | | convertible_to<decltype(j - j), iota_diff_t<I>>>{}); |
18443 | | }; |
18444 | | |
18445 | | template <typename I> |
18446 | | NANO_CONCEPT advanceable = decrementable<I> && totally_ordered<I> && |
18447 | | requires_<advanceable_concept, I>; |
18448 | | |
18449 | | template <typename W> |
18450 | | constexpr auto iota_view_iter_cat_helper() |
18451 | | { |
18452 | | if constexpr (detail::advanceable<W>) { |
18453 | | return random_access_iterator_tag{}; |
18454 | | } |
18455 | | else if constexpr (detail::decrementable<W>) { |
18456 | | return bidirectional_iterator_tag{}; |
18457 | | } |
18458 | | else if constexpr (incrementable<W>) { |
18459 | | return forward_iterator_tag{}; |
18460 | | } |
18461 | | else { |
18462 | | return input_iterator_tag{}; |
18463 | | } |
18464 | | } |
18465 | | |
18466 | | } // namespace detail |
18467 | | |
18468 | | template <typename W, typename Bound = unreachable_sentinel_t> |
18469 | | struct iota_view : view_interface<iota_view<W, Bound>> { |
18470 | | static_assert(weakly_incrementable<W>); |
18471 | | static_assert(semiregular<Bound>); |
18472 | | static_assert(detail::weakly_equality_comparable_with<W, Bound>); |
18473 | | |
18474 | | private: |
18475 | | struct sentinel; |
18476 | | |
18477 | | struct iterator { |
18478 | | private: |
18479 | | friend struct sentinel; |
18480 | | W value_ = W(); |
18481 | | |
18482 | | public: |
18483 | | using iterator_category = |
18484 | | decltype(detail::iota_view_iter_cat_helper<W>()); |
18485 | | using value_type = W; |
18486 | | using difference_type = detail::iota_diff_t<W>; |
18487 | | // Extension: legacy typedefs |
18488 | | using pointer = void; |
18489 | | using reference = W; |
18490 | | |
18491 | | iterator() = default; |
18492 | | |
18493 | | constexpr explicit iterator(W value) : value_(value) {} |
18494 | | |
18495 | | constexpr W operator*() const |
18496 | | noexcept(std::is_nothrow_copy_constructible_v<W>) |
18497 | | { |
18498 | | return value_; |
18499 | | } |
18500 | | |
18501 | | constexpr iterator& operator++() |
18502 | | { |
18503 | | ++value_; |
18504 | | return *this; |
18505 | | } |
18506 | | |
18507 | | constexpr auto operator++(int) |
18508 | | { |
18509 | | if constexpr (incrementable<W>) { |
18510 | | auto tmp = *this; |
18511 | | ++*this; |
18512 | | return tmp; |
18513 | | } |
18514 | | else { |
18515 | | ++*this; |
18516 | | } |
18517 | | } |
18518 | | |
18519 | | template <typename WW = W> |
18520 | | constexpr auto operator--() |
18521 | | -> std::enable_if_t<detail::decrementable<WW>, iterator&> |
18522 | | { |
18523 | | --value_; |
18524 | | return *this; |
18525 | | } |
18526 | | |
18527 | | constexpr iterator operator--(int) |
18528 | | { |
18529 | | auto tmp = *this; |
18530 | | ++*this; |
18531 | | return tmp; |
18532 | | } |
18533 | | |
18534 | | template <typename WW = W> |
18535 | | constexpr auto operator+=(difference_type n) |
18536 | | -> std::enable_if_t<detail::advanceable<WW>, iterator&> |
18537 | | { |
18538 | | if constexpr (integral<W> && !signed_integral<W>) { |
18539 | | if (n >= difference_type(0)) { |
18540 | | value_ += static_cast<W>(n); |
18541 | | } |
18542 | | else { |
18543 | | value_ -= static_cast<W>(-n); |
18544 | | } |
18545 | | } |
18546 | | else { |
18547 | | value_ += n; |
18548 | | } |
18549 | | return *this; |
18550 | | } |
18551 | | |
18552 | | template <typename WW = W> |
18553 | | constexpr auto operator-=(difference_type n) |
18554 | | -> std::enable_if_t<detail::advanceable<WW>, iterator&> |
18555 | | { |
18556 | | if constexpr (integral<W> && !signed_integral<W>) { |
18557 | | if (n >= difference_type(0)) { |
18558 | | value_ -= static_cast<W>(n); |
18559 | | } |
18560 | | else { |
18561 | | value_ += static_cast<W>(-n); |
18562 | | } |
18563 | | } |
18564 | | else { |
18565 | | value_ -= n; |
18566 | | } |
18567 | | return *this; |
18568 | | } |
18569 | | |
18570 | | template <typename WW = W> |
18571 | | constexpr auto operator[](difference_type n) const |
18572 | | -> std::enable_if_t<detail::advanceable<WW>, W> |
18573 | | { |
18574 | | return W(value_ + n); |
18575 | | } |
18576 | | |
18577 | | template <typename WW = W> |
18578 | | friend constexpr auto operator==(const iterator& x, const iterator& y) |
18579 | | -> std::enable_if_t<equality_comparable<WW>, bool> |
18580 | | { |
18581 | | return x.value_ == y.value_; |
18582 | | } |
18583 | | |
18584 | | template <typename WW = W> |
18585 | | friend constexpr auto operator!=(const iterator& x, const iterator& y) |
18586 | | -> std::enable_if_t<equality_comparable<WW>, bool> |
18587 | | { |
18588 | | return !(x == y); |
18589 | | } |
18590 | | |
18591 | | template <typename WW = W> |
18592 | | friend constexpr auto operator<(const iterator& x, const iterator& y) |
18593 | | -> std::enable_if_t<totally_ordered<WW>, bool> |
18594 | | { |
18595 | | return x.value_ < y.value_; |
18596 | | } |
18597 | | |
18598 | | template <typename WW = W> |
18599 | | friend constexpr auto operator>(const iterator& x, const iterator& y) |
18600 | | -> std::enable_if_t<totally_ordered<WW>, bool> |
18601 | | { |
18602 | | return y < x; |
18603 | | } |
18604 | | |
18605 | | template <typename WW = W> |
18606 | | friend constexpr auto operator<=(const iterator& x, const iterator& y) |
18607 | | -> std::enable_if_t<totally_ordered<WW>, bool> |
18608 | | { |
18609 | | return !(y < x); |
18610 | | } |
18611 | | |
18612 | | template <typename WW = W> |
18613 | | friend constexpr auto operator>=(const iterator& x, const iterator& y) |
18614 | | -> std::enable_if_t<totally_ordered<WW>, bool> |
18615 | | { |
18616 | | return !(x < y); |
18617 | | } |
18618 | | |
18619 | | template <typename WW = W> |
18620 | | friend constexpr auto operator+(iterator i, difference_type n) |
18621 | | -> std::enable_if_t<detail::advanceable<WW>, iterator> |
18622 | | { |
18623 | | return i += n; |
18624 | | } |
18625 | | |
18626 | | template <typename WW = W> |
18627 | | friend constexpr auto operator+(difference_type n, iterator i) |
18628 | | -> std::enable_if_t<detail::advanceable<WW>, iterator> |
18629 | | { |
18630 | | return i + n; |
18631 | | } |
18632 | | |
18633 | | template <typename WW = W> |
18634 | | friend constexpr auto operator-(iterator i, difference_type n) |
18635 | | -> std::enable_if_t<detail::advanceable<WW>, iterator> |
18636 | | { |
18637 | | return i -= n; |
18638 | | } |
18639 | | |
18640 | | template <typename WW = W> |
18641 | | friend constexpr auto operator-(const iterator& x, const iterator& y) |
18642 | | -> std::enable_if_t<detail::advanceable<WW>, difference_type> |
18643 | | { |
18644 | | using D = difference_type; |
18645 | | if constexpr (integral<D>) { |
18646 | | if constexpr (signed_integral<D>) { |
18647 | | return D(D(x.value_) - D(y.value_)); |
18648 | | } |
18649 | | else { |
18650 | | return (y.value_ > x.value) ? D(-D(y.value_ - x.value_)) |
18651 | | : D(x.value_ - y.value_); |
18652 | | } |
18653 | | } |
18654 | | else { |
18655 | | return x.value_ - y.value_; |
18656 | | } |
18657 | | } |
18658 | | }; |
18659 | | |
18660 | | struct sentinel { |
18661 | | private: |
18662 | | Bound bound_ = Bound(); |
18663 | | |
18664 | | public: |
18665 | | sentinel() = default; |
18666 | | constexpr explicit sentinel(Bound bound) : bound_(bound) {} |
18667 | | |
18668 | | friend constexpr bool operator==(const iterator& i, const sentinel& s) |
18669 | | { |
18670 | | return i.value_ == s.bound_; |
18671 | | } |
18672 | | |
18673 | | friend constexpr bool operator==(const sentinel& s, const iterator& i) |
18674 | | { |
18675 | | return i == s; |
18676 | | } |
18677 | | |
18678 | | friend constexpr bool operator!=(const iterator& i, const sentinel& s) |
18679 | | { |
18680 | | return !(i == s); |
18681 | | } |
18682 | | |
18683 | | friend constexpr bool operator!=(const sentinel& s, const iterator& i) |
18684 | | { |
18685 | | return !(i == s); |
18686 | | } |
18687 | | |
18688 | | template <typename WW = W> |
18689 | | friend constexpr auto operator-(const iterator& i, const sentinel& s) |
18690 | | -> std::enable_if_t<sized_sentinel_for<Bound, WW>, |
18691 | | iter_difference_t<WW>> |
18692 | | { |
18693 | | return i.value_ - s.bound_; |
18694 | | } |
18695 | | |
18696 | | template <typename WW = W> |
18697 | | friend constexpr auto operator-(const sentinel& s, const iterator& i) |
18698 | | -> std::enable_if_t<sized_sentinel_for<Bound, WW>, |
18699 | | iter_difference_t<WW>> |
18700 | | { |
18701 | | return -(i - s); |
18702 | | } |
18703 | | }; |
18704 | | |
18705 | | W value_ = W(); |
18706 | | Bound bound_ = Bound(); |
18707 | | |
18708 | | public: |
18709 | | iota_view() = default; |
18710 | | |
18711 | | constexpr explicit iota_view(W value) : value_(value) {} |
18712 | | |
18713 | | constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound) |
18714 | | : value_(value), bound_(bound) |
18715 | | { |
18716 | | } |
18717 | | |
18718 | | constexpr iota_view(iterator first, sentinel last) |
18719 | | : iota_view(*first, last.bound_) |
18720 | | { |
18721 | | } |
18722 | | |
18723 | | constexpr iterator begin() const |
18724 | | { |
18725 | | return iterator{value_}; |
18726 | | } |
18727 | | |
18728 | | template <typename WW = W, std::enable_if_t<!same_as<WW, Bound>, int> = 0> |
18729 | | constexpr auto end() const |
18730 | | { |
18731 | | if constexpr (same_as<Bound, unreachable_sentinel_t>) { |
18732 | | return unreachable_sentinel; |
18733 | | } |
18734 | | else { |
18735 | | return sentinel{bound_}; |
18736 | | } |
18737 | | } |
18738 | | |
18739 | | template <typename WW = W, std::enable_if_t<same_as<WW, Bound>, int> = 0> |
18740 | | constexpr iterator end() const |
18741 | | { |
18742 | | return iterator{bound_}; |
18743 | | } |
18744 | | |
18745 | | template <typename WW = W, |
18746 | | typename BB = Bound, |
18747 | | std::enable_if_t<(same_as<WW, BB> && detail::advanceable<W>) || |
18748 | | (integral<WW> && integral<BB>) || |
18749 | | sized_sentinel_for<BB, WW>, |
18750 | | int> = 0> |
18751 | | constexpr auto size() const |
18752 | | { |
18753 | | constexpr auto make_unsigned_like = [](auto i) { |
18754 | | return std::make_unsigned_t<decltype(i)>(i); |
18755 | | }; |
18756 | | |
18757 | | if constexpr (integral<W> && integral<Bound>) { |
18758 | | return (value_ < 0) |
18759 | | ? ((bound_ < 0) ? make_unsigned_like(-value_) - |
18760 | | make_unsigned_like(-bound_) |
18761 | | : make_unsigned_like(bound_) - |
18762 | | make_unsigned_like(-value_)) |
18763 | | : make_unsigned_like(bound_) - |
18764 | | make_unsigned_like(value_); |
18765 | | } |
18766 | | else { |
18767 | | make_unsigned_like(bound_ - value_); |
18768 | | } |
18769 | | } |
18770 | | }; |
18771 | | |
18772 | | template <typename W, |
18773 | | typename Bound, |
18774 | | std::enable_if_t<!integral<W> || !integral<Bound> || |
18775 | | (signed_integral<W> == signed_integral<Bound>), |
18776 | | int> = 0> |
18777 | | iota_view(W, Bound) -> iota_view<W, Bound>; |
18778 | | |
18779 | | template <typename W, typename Bound> |
18780 | | inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true; |
18781 | | |
18782 | | namespace views { |
18783 | | |
18784 | | namespace detail { |
18785 | | |
18786 | | struct iota_view_fn { |
18787 | | template <typename W> |
18788 | | constexpr auto operator()(W&& value) const |
18789 | | noexcept(noexcept(iota_view{std::forward<W>(value)})) |
18790 | | -> decltype(iota_view(std::forward<W>(value))) |
18791 | | { |
18792 | | return iota_view(std::forward<W>(value)); |
18793 | | } |
18794 | | |
18795 | | template <typename W, typename Bound> |
18796 | | constexpr auto operator()(W&& value, Bound&& bound) const |
18797 | | noexcept(noexcept(iota_view{std::forward<W>(value), |
18798 | | std::forward<Bound>(bound)})) |
18799 | | -> decltype(iota_view(std::forward<W>(value), |
18800 | | std::forward<Bound>(bound))) |
18801 | | { |
18802 | | return iota_view{std::forward<W>(value), |
18803 | | std::forward<Bound>(bound)}; |
18804 | | } |
18805 | | }; |
18806 | | |
18807 | | } // namespace detail |
18808 | | |
18809 | | NANO_INLINE_VAR(detail::iota_view_fn, iota) |
18810 | | |
18811 | | } // namespace views |
18812 | | |
18813 | | NANO_END_NAMESPACE |
18814 | | |
18815 | | #endif |
18816 | | |
18817 | | // nanorange/views/istream.hpp |
18818 | | // |
18819 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
18820 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
18821 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
18822 | | |
18823 | | #ifndef NANORANGE_VIEWS_ISTREAM_HPP_INCLUDED |
18824 | | #define NANORANGE_VIEWS_ISTREAM_HPP_INCLUDED |
18825 | | |
18826 | | #include <iosfwd> |
18827 | | |
18828 | | NANO_BEGIN_NAMESPACE |
18829 | | |
18830 | | namespace detail { |
18831 | | |
18832 | | struct StreamExtractable_req { |
18833 | | template <typename Val, typename CharT, typename Traits> |
18834 | | auto requires_(std::basic_istream<CharT, Traits>& is, Val& t) |
18835 | | -> decltype(is >> t); |
18836 | | }; |
18837 | | |
18838 | | template <typename Val, typename CharT, typename Traits> |
18839 | | NANO_CONCEPT StreamExtractable = |
18840 | | requires_<StreamExtractable_req, Val, CharT, Traits>; |
18841 | | |
18842 | | } // namespace detail |
18843 | | |
18844 | | template <typename Val, |
18845 | | typename CharT, |
18846 | | typename Traits = std::char_traits<CharT>> |
18847 | | struct basic_istream_view |
18848 | | : view_interface<basic_istream_view<Val, CharT, Traits>> { |
18849 | | static_assert(movable<Val>); |
18850 | | static_assert(default_initializable<Val>); |
18851 | | static_assert(detail::StreamExtractable<Val, CharT, Traits>); |
18852 | | |
18853 | | basic_istream_view() = default; |
18854 | | |
18855 | | constexpr explicit basic_istream_view( |
18856 | | std::basic_istream<CharT, Traits>& stream) |
18857 | | : stream_(std::addressof(stream)) |
18858 | | { |
18859 | | } |
18860 | | |
18861 | | constexpr auto begin() |
18862 | | { |
18863 | | if (stream_) { |
18864 | | *stream_ >> object_; |
18865 | | } |
18866 | | return iterator{*this}; |
18867 | | } |
18868 | | |
18869 | | constexpr default_sentinel_t end() const noexcept |
18870 | | { |
18871 | | return default_sentinel; |
18872 | | } |
18873 | | |
18874 | | private: |
18875 | | struct iterator { |
18876 | | using iterator_category = input_iterator_tag; |
18877 | | using difference_type = std::ptrdiff_t; |
18878 | | using value_type = Val; |
18879 | | |
18880 | | iterator() = default; |
18881 | | |
18882 | | constexpr explicit iterator(basic_istream_view& parent) noexcept |
18883 | | : parent_(std::addressof(parent)) |
18884 | | { |
18885 | | } |
18886 | | |
18887 | | // Disable move-only iterator until views support them properly |
18888 | | #if 0 |
18889 | | iterator(const iterator&) = delete; |
18890 | | iterator(iterator&&) = default; |
18891 | | |
18892 | | iterator& operator=(const iterator&) = delete; |
18893 | | iterator& operator=(iterator&&) = default; |
18894 | | #endif |
18895 | | iterator& operator++() |
18896 | | { |
18897 | | *parent_->stream_ >> parent_->object_; |
18898 | | return *this; |
18899 | | } |
18900 | | |
18901 | | void operator++(int) |
18902 | | { |
18903 | | ++*this; |
18904 | | } |
18905 | | |
18906 | | Val& operator*() const |
18907 | | { |
18908 | | return parent_->object_; |
18909 | | } |
18910 | | |
18911 | | friend bool operator==(const iterator& x, default_sentinel_t) |
18912 | | { |
18913 | | return x.done(); |
18914 | | } |
18915 | | |
18916 | | friend bool operator==(default_sentinel_t s, const iterator& x) |
18917 | | { |
18918 | | return x == s; |
18919 | | } |
18920 | | |
18921 | | friend bool operator!=(const iterator& x, default_sentinel_t s) |
18922 | | { |
18923 | | return !(x == s); |
18924 | | } |
18925 | | |
18926 | | friend bool operator!=(default_sentinel_t s, const iterator& x) |
18927 | | { |
18928 | | return !(x == s); |
18929 | | } |
18930 | | |
18931 | | private: |
18932 | | [[nodiscard]] bool done() const |
18933 | | { |
18934 | | return parent_ == nullptr || parent_->stream_ == nullptr || |
18935 | | !*parent_->stream_; |
18936 | | } |
18937 | | |
18938 | | basic_istream_view* parent_{}; |
18939 | | }; |
18940 | | |
18941 | | std::basic_istream<CharT, Traits>* stream_{}; |
18942 | | Val object_ = Val(); |
18943 | | }; |
18944 | | |
18945 | | template <typename Val, typename CharT, typename Traits> |
18946 | | auto istream_view(std::basic_istream<CharT, Traits>& s) |
18947 | | -> basic_istream_view<Val, CharT, Traits> |
18948 | | { |
18949 | | return basic_istream_view<Val, CharT, Traits>{s}; |
18950 | | } |
18951 | | |
18952 | | NANO_END_NAMESPACE |
18953 | | |
18954 | | #endif |
18955 | | |
18956 | | // nanorange/views/join.hpp |
18957 | | // |
18958 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
18959 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
18960 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
18961 | | |
18962 | | #ifndef NANORANGE_VIEWS_JOIN_HPP_INCLUDED |
18963 | | #define NANORANGE_VIEWS_JOIN_HPP_INCLUDED |
18964 | | |
18965 | | NANO_BEGIN_NAMESPACE |
18966 | | |
18967 | | namespace detail { |
18968 | | |
18969 | | template <typename V, bool InnerIsReference> |
18970 | | struct join_view_data { |
18971 | | V base_ = V(); |
18972 | | }; |
18973 | | |
18974 | | template <typename V> |
18975 | | struct join_view_data<V, false> { |
18976 | | V base_ = V(); |
18977 | | all_view<range_reference_t<V>> inner_ = |
18978 | | all_view<range_reference_t<V>>(); |
18979 | | }; |
18980 | | |
18981 | | template <typename B> |
18982 | | constexpr auto join_view_iter_cat_helper() |
18983 | | { |
18984 | | constexpr bool ref_is_glvalue = |
18985 | | std::is_reference_v<range_reference_t<B>>; |
18986 | | |
18987 | | if constexpr (ref_is_glvalue) { |
18988 | | using OuterCat = iterator_category_t<iterator_t<B>>; |
18989 | | using InnerCat = |
18990 | | iterator_category_t<iterator_t<range_reference_t<B>>>; |
18991 | | |
18992 | | if constexpr (derived_from<OuterCat, bidirectional_iterator_tag> && |
18993 | | derived_from<InnerCat, bidirectional_iterator_tag>) { |
18994 | | return bidirectional_iterator_tag{}; |
18995 | | } |
18996 | | else if constexpr (derived_from<OuterCat, forward_iterator_tag> && |
18997 | | derived_from<InnerCat, forward_iterator_tag>) { |
18998 | | return forward_iterator_tag{}; |
18999 | | } |
19000 | | else { |
19001 | | return input_iterator_tag{}; |
19002 | | } |
19003 | | } |
19004 | | else { |
19005 | | return input_iterator_tag{}; |
19006 | | } |
19007 | | } |
19008 | | |
19009 | | } // namespace detail |
19010 | | |
19011 | | namespace join_view_ { |
19012 | | |
19013 | | template <typename V> |
19014 | | struct join_view : view_interface<join_view<V>> { |
19015 | | private: |
19016 | | static_assert(input_range<V>); |
19017 | | static_assert(view<V>); |
19018 | | static_assert(input_range<range_reference_t<V>>); |
19019 | | static_assert(std::is_reference_v<range_reference_t<V>> || |
19020 | | view<range_value_t<V>>); |
19021 | | |
19022 | | using InnerRng = range_reference_t<V>; |
19023 | | |
19024 | | template <bool> |
19025 | | struct sentinel; |
19026 | | |
19027 | | template <bool Const> |
19028 | | struct iterator { |
19029 | | friend struct sentinel<Const>; |
19030 | | |
19031 | | template <typename B> |
19032 | | static constexpr bool ref_is_glvalue = |
19033 | | std::is_reference_v<range_reference_t<B>>; |
19034 | | |
19035 | | using Base = detail::conditional_t<Const, const V, V>; |
19036 | | |
19037 | | // https://github.com/ericniebler/stl2/issues/604 |
19038 | | using Parent = detail::conditional_t<Const && ref_is_glvalue<Base>, |
19039 | | const join_view, |
19040 | | join_view>; |
19041 | | |
19042 | | iterator_t<Base> outer_ = iterator_t<Base>(); |
19043 | | iterator_t<range_reference_t<Base>> inner_ = |
19044 | | iterator_t<range_reference_t<Base>>(); |
19045 | | Parent* parent_ = nullptr; |
19046 | | |
19047 | | template <typename B = Base> |
19048 | | constexpr decltype(auto) update_inner(range_reference_t<Base> x) |
19049 | | { |
19050 | | if constexpr (ref_is_glvalue<B>) { |
19051 | | return (x); |
19052 | | } |
19053 | | else { |
19054 | | return (parent_->data_.inner_ = views::all(x)); |
19055 | | } |
19056 | | } |
19057 | | |
19058 | | constexpr void satisfy() |
19059 | | { |
19060 | | for (; outer_ != ranges::end(parent_->data_.base_); ++outer_) { |
19061 | | auto& inner = update_inner(*outer_); |
19062 | | inner_ = ranges::begin(inner); |
19063 | | if (inner_ != ranges::end(inner)) { |
19064 | | return; |
19065 | | } |
19066 | | } |
19067 | | |
19068 | | if constexpr (ref_is_glvalue<Base>) { |
19069 | | inner_ = iterator_t<range_reference_t<Base>>(); |
19070 | | } |
19071 | | } |
19072 | | |
19073 | | public: |
19074 | | // using iterator_concept = ... |
19075 | | using iterator_category = |
19076 | | decltype(detail::join_view_iter_cat_helper<Base>()); |
19077 | | using value_type = range_value_t<range_reference_t<Base>>; |
19078 | | using difference_type = nano::common_type_t< |
19079 | | range_difference_t<Base>, |
19080 | | range_difference_t<range_reference_t<Base>>>; |
19081 | | // Extension: legacy typedefs |
19082 | | using pointer = iterator_t<Base>; |
19083 | | using reference = range_reference_t<range_reference_t<Base>>; |
19084 | | |
19085 | | iterator() = default; |
19086 | | |
19087 | | constexpr iterator(Parent& parent, iterator_t<Base> outer) |
19088 | | : outer_(std::move(outer)), parent_(std::addressof(parent)) |
19089 | | { |
19090 | | satisfy(); |
19091 | | } |
19092 | | |
19093 | | // constexpr iterator(iterator<!Const>); |
19094 | | |
19095 | | constexpr decltype(auto) operator*() const |
19096 | | { |
19097 | | return *inner_; |
19098 | | } |
19099 | | |
19100 | | template <typename B = Base> |
19101 | | constexpr auto operator->() const |
19102 | | -> std::enable_if_t<detail::has_arrow<B>, iterator_t<Base>> |
19103 | | { |
19104 | | return inner_; |
19105 | | } |
19106 | | |
19107 | | private: |
19108 | | template <typename B = Base> |
19109 | | constexpr decltype(auto) get_inner_rng() |
19110 | | { |
19111 | | if constexpr (ref_is_glvalue<B>) { |
19112 | | return (*outer_); |
19113 | | } |
19114 | | else { |
19115 | | return (parent_->data_.inner_); |
19116 | | } |
19117 | | } |
19118 | | |
19119 | | public: |
19120 | | template <typename B = Base> |
19121 | | constexpr iterator& operator++() |
19122 | | { |
19123 | | auto&& inner_rng = get_inner_rng(); |
19124 | | |
19125 | | if (++inner_ == ranges::end(inner_rng)) { |
19126 | | ++outer_; |
19127 | | satisfy(); |
19128 | | } |
19129 | | |
19130 | | return *this; |
19131 | | } |
19132 | | |
19133 | | template <typename B = Base> |
19134 | | constexpr auto operator++(int) |
19135 | | -> std::enable_if_t<!(ref_is_glvalue<B> && forward_range<B> && |
19136 | | forward_range<range_reference_t<B>>)> |
19137 | | { |
19138 | | ++*this; |
19139 | | } |
19140 | | |
19141 | | template <typename B = Base> |
19142 | | constexpr auto operator++(int) |
19143 | | -> std::enable_if_t<ref_is_glvalue<B> && forward_range<B> && |
19144 | | forward_range<range_reference_t<B>>, |
19145 | | iterator> |
19146 | | { |
19147 | | auto tmp = *this; |
19148 | | ++*this; |
19149 | | return tmp; |
19150 | | } |
19151 | | |
19152 | | template <typename B = Base> |
19153 | | constexpr auto operator--() -> std::enable_if_t< |
19154 | | ref_is_glvalue<B> && bidirectional_range<B> && |
19155 | | bidirectional_range<range_reference_t<B>>, |
19156 | | iterator&> |
19157 | | { |
19158 | | if (outer_ == ranges::end(parent_->data_.base_)) { |
19159 | | inner_ = ranges::end(*outer_); |
19160 | | } |
19161 | | |
19162 | | while (inner_ == ranges::begin(*outer_)) { |
19163 | | inner_ = ranges::end(*--outer_); |
19164 | | } |
19165 | | --inner_; |
19166 | | return *this; |
19167 | | } |
19168 | | |
19169 | | template <typename B = Base> |
19170 | | constexpr auto operator--(int) -> std::enable_if_t< |
19171 | | ref_is_glvalue<B> && bidirectional_range<B> && |
19172 | | bidirectional_range<range_reference_t<B>>, |
19173 | | iterator> |
19174 | | { |
19175 | | auto tmp = *this; |
19176 | | --*this; |
19177 | | return *tmp; |
19178 | | } |
19179 | | |
19180 | | template <typename B = Base> |
19181 | | friend constexpr auto operator==(const iterator& x, |
19182 | | const iterator& y) |
19183 | | -> std::enable_if_t< |
19184 | | ref_is_glvalue<B> && equality_comparable<iterator_t<B>> && |
19185 | | equality_comparable<iterator_t<range_reference_t<B>>>, |
19186 | | bool> |
19187 | | { |
19188 | | return x.outer_ == y.outer_ && x.inner_ == y.inner_; |
19189 | | } |
19190 | | |
19191 | | template <typename B = Base> |
19192 | | friend constexpr auto operator!=(const iterator& x, |
19193 | | const iterator& y) |
19194 | | -> std::enable_if_t< |
19195 | | ref_is_glvalue<B> && equality_comparable<iterator_t<B>> && |
19196 | | equality_comparable<iterator_t<range_reference_t<B>>>, |
19197 | | bool> |
19198 | | { |
19199 | | return !(x == y); |
19200 | | } |
19201 | | |
19202 | | friend constexpr decltype(auto) |
19203 | | iter_move(const iterator& i) noexcept( |
19204 | | noexcept(ranges::iter_move(i.inner_))) |
19205 | | { |
19206 | | return ranges::iter_move(i.inner_); |
19207 | | } |
19208 | | |
19209 | | friend constexpr void |
19210 | | iter_swap(const iterator& x, const iterator& y) noexcept( |
19211 | | noexcept(ranges::iter_swap(x.inner_, y.inner_))) |
19212 | | { |
19213 | | ranges::iter_swap(x.inner_, y.inner_); |
19214 | | } |
19215 | | }; |
19216 | | |
19217 | | template <bool Const> |
19218 | | struct sentinel { |
19219 | | private: |
19220 | | using Parent = |
19221 | | detail::conditional_t<Const, const join_view, join_view>; |
19222 | | using Base = detail::conditional_t<Const, const V, V>; |
19223 | | |
19224 | | sentinel_t<Base> end_ = sentinel_t<Base>(); |
19225 | | |
19226 | | public: |
19227 | | sentinel() = default; |
19228 | | |
19229 | | constexpr explicit sentinel(Parent& parent) |
19230 | | : end_(ranges::end(parent.data_.base_)) |
19231 | | { |
19232 | | } |
19233 | | |
19234 | | // constexpr sentinel(sentinel<!Const> s); |
19235 | | |
19236 | | friend constexpr bool operator==(const iterator<Const>& x, |
19237 | | const sentinel& y) |
19238 | | { |
19239 | | return x.outer_ == y.end_; |
19240 | | } |
19241 | | |
19242 | | friend constexpr bool operator!=(const iterator<Const>& x, |
19243 | | const sentinel& y) |
19244 | | { |
19245 | | return !(x == y); |
19246 | | } |
19247 | | |
19248 | | friend constexpr bool operator==(const sentinel& x, |
19249 | | const iterator<Const>& y) |
19250 | | { |
19251 | | return y == x; |
19252 | | } |
19253 | | |
19254 | | friend constexpr bool operator!=(const sentinel& x, |
19255 | | const iterator<Const>& y) |
19256 | | { |
19257 | | return !(y == x); |
19258 | | } |
19259 | | }; |
19260 | | |
19261 | | detail::join_view_data<V, std::is_reference_v<InnerRng>> data_{}; |
19262 | | |
19263 | | public: |
19264 | | join_view() = default; |
19265 | | |
19266 | | constexpr explicit join_view(V base) : data_{std::move(base)} {} |
19267 | | |
19268 | | constexpr auto begin() |
19269 | | { |
19270 | | return iterator<detail::simple_view<V>>{*this, |
19271 | | ranges::begin(data_.base_)}; |
19272 | | } |
19273 | | |
19274 | | template <typename VV = V, |
19275 | | std::enable_if_t< |
19276 | | input_range<const VV> && |
19277 | | std::is_reference_v<range_reference_t<const VV>>, |
19278 | | int> = 0> |
19279 | | constexpr auto begin() const |
19280 | | { |
19281 | | return iterator<true>{*this, ranges::begin(data_.base_)}; |
19282 | | } |
19283 | | |
19284 | | constexpr auto end() |
19285 | | { |
19286 | | if constexpr (forward_range<V> && std::is_reference_v<InnerRng> && |
19287 | | forward_range<InnerRng> && common_range<V> && |
19288 | | common_range<InnerRng>) { |
19289 | | return iterator<detail::simple_view<V>>{ |
19290 | | *this, ranges::end(data_.base_)}; |
19291 | | } |
19292 | | else { |
19293 | | return sentinel<detail::simple_view<V>>{*this}; |
19294 | | } |
19295 | | } |
19296 | | |
19297 | | template <typename VV = V, |
19298 | | std::enable_if_t< |
19299 | | input_range<const VV> && |
19300 | | std::is_reference_v<range_reference_t<const VV>>, |
19301 | | int> = 0> |
19302 | | constexpr auto end() const |
19303 | | { |
19304 | | if constexpr (forward_range<const V> && |
19305 | | std::is_reference_v<range_reference_t<const V>> && |
19306 | | forward_range<range_reference_t<const V>> && |
19307 | | common_range<const V> && |
19308 | | common_range<range_reference_t<const V>>) { |
19309 | | return iterator<true>{*this, ranges::end(data_.base_)}; |
19310 | | } |
19311 | | else { |
19312 | | return sentinel<true>{*this}; |
19313 | | } |
19314 | | } |
19315 | | }; |
19316 | | |
19317 | | template <typename R> |
19318 | | explicit join_view(R&&) -> join_view<all_view<R>>; |
19319 | | |
19320 | | } // namespace join_view_ |
19321 | | |
19322 | | using join_view_::join_view; |
19323 | | |
19324 | | namespace detail { |
19325 | | |
19326 | | struct join_view_fn { |
19327 | | template <typename E> |
19328 | | constexpr auto operator()(E&& e) const |
19329 | | -> decltype(join_view{std::forward<E>(e)}) |
19330 | | { |
19331 | | return join_view{std::forward<E>(e)}; |
19332 | | } |
19333 | | }; |
19334 | | |
19335 | | template <> |
19336 | | inline constexpr bool is_raco<join_view_fn> = true; |
19337 | | |
19338 | | } // namespace detail |
19339 | | |
19340 | | namespace views { |
19341 | | |
19342 | | NANO_INLINE_VAR(nano::detail::join_view_fn, join) |
19343 | | |
19344 | | } |
19345 | | |
19346 | | NANO_END_NAMESPACE |
19347 | | |
19348 | | #endif |
19349 | | |
19350 | | // nanorange/views/reverse.hpp |
19351 | | // |
19352 | | // Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com) |
19353 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
19354 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
19355 | | |
19356 | | #ifndef NANORANGE_VIEWS_REVERSE_HPP_INCLUDED |
19357 | | #define NANORANGE_VIEWS_REVERSE_HPP_INCLUDED |
19358 | | |
19359 | | #include <optional> |
19360 | | |
19361 | | NANO_BEGIN_NAMESPACE |
19362 | | |
19363 | | namespace detail { |
19364 | | |
19365 | | template <bool IsCommonRange, typename> |
19366 | | struct reverse_view_cache {}; |
19367 | | |
19368 | | template <typename I> |
19369 | | struct reverse_view_cache<false, I> { |
19370 | | std::optional<I> cached{}; |
19371 | | }; |
19372 | | |
19373 | | } // namespace detail |
19374 | | |
19375 | | template <typename V> |
19376 | | struct reverse_view |
19377 | | : view_interface<reverse_view<V>>, |
19378 | | private detail::reverse_view_cache<common_range<V>, iterator_t<V>> { |
19379 | | static_assert(view<V>); |
19380 | | static_assert(bidirectional_range<V>); |
19381 | | |
19382 | | reverse_view() = default; |
19383 | | |
19384 | 0 | constexpr explicit reverse_view(V r) : base_(std::move(r)) {} |
19385 | | |
19386 | | constexpr V base() const |
19387 | | { |
19388 | | return base_; |
19389 | | } |
19390 | | |
19391 | | constexpr reverse_iterator<iterator_t<V>> begin() |
19392 | 0 | { |
19393 | 0 | if constexpr (common_range<V>) { |
19394 | 0 | return nano::make_reverse_iterator(ranges::end(base_)); |
19395 | 0 | } |
19396 | 0 | else { |
19397 | 0 | auto& c = this->cached; |
19398 | 0 | if (!c.has_value()) { |
19399 | 0 | c = ranges::next(ranges::begin(base_), ranges::end(base_)); |
19400 | 0 | } |
19401 | 0 | return nano::make_reverse_iterator(*c); |
19402 | 0 | } |
19403 | 0 | } |
19404 | | |
19405 | | template <typename VV = V> |
19406 | | constexpr auto begin() const |
19407 | | -> std::enable_if_t<common_range<const VV>, |
19408 | | reverse_iterator<iterator_t<const VV>>> |
19409 | | { |
19410 | | return nano::make_reverse_iterator(ranges::end(base_)); |
19411 | | } |
19412 | | |
19413 | | constexpr reverse_iterator<iterator_t<V>> end() |
19414 | 0 | { |
19415 | 0 | return nano::make_reverse_iterator(ranges::begin(base_)); |
19416 | 0 | } |
19417 | | |
19418 | | template <typename VV = V> |
19419 | | constexpr auto end() const |
19420 | | -> std::enable_if_t<common_range<const VV>, |
19421 | | reverse_iterator<iterator_t<const VV>>> |
19422 | | { |
19423 | | return nano::make_reverse_iterator(ranges::begin(base_)); |
19424 | | } |
19425 | | |
19426 | | template <typename VV = V, std::enable_if_t<sized_range<VV>, int> = 0> |
19427 | | constexpr auto size() |
19428 | | { |
19429 | | return ranges::size(base_); |
19430 | | } |
19431 | | |
19432 | | template <typename VV = V, std::enable_if_t<sized_range<const VV>, int> = 0> |
19433 | | constexpr auto size() const |
19434 | | { |
19435 | | return ranges::size(base_); |
19436 | | } |
19437 | | |
19438 | | private: |
19439 | | V base_ = V{}; |
19440 | | }; |
19441 | | |
19442 | | template <typename R> |
19443 | | reverse_view(R&&) -> reverse_view<all_view<R>>; |
19444 | | |
19445 | | namespace detail { |
19446 | | |
19447 | | struct reverse_view_fn { |
19448 | | private: |
19449 | | template <typename R> |
19450 | | static constexpr auto impl(reverse_view<R> r, detail::priority_tag<1>) |
19451 | | { |
19452 | | return r.base(); |
19453 | | } |
19454 | | |
19455 | | template <typename I, subrange_kind K> |
19456 | | static constexpr auto impl( |
19457 | | subrange<reverse_iterator<I>, reverse_iterator<I>, K> s, |
19458 | | detail::priority_tag<1>) |
19459 | | { |
19460 | | if constexpr (K == subrange_kind::sized) { |
19461 | | return subrange<I, I, K>(s.end().base(), s.begin().base(), |
19462 | | s.size()); |
19463 | | } |
19464 | | else { |
19465 | | return subrange<I, I, K>(s.end().base(), s.begin().base()); |
19466 | | } |
19467 | | } |
19468 | | |
19469 | | template <typename R> |
19470 | | static constexpr auto impl(R&& r, detail::priority_tag<0>) |
19471 | | -> decltype(reverse_view{std::forward<R>(r)}) |
19472 | 0 | { |
19473 | 0 | return reverse_view{std::forward<R>(r)}; |
19474 | 0 | } |
19475 | | |
19476 | | public: |
19477 | | template <typename R> |
19478 | | constexpr auto operator()(R&& r) const |
19479 | | -> decltype(impl(std::forward<R>(r), priority_tag<1>{})) |
19480 | 0 | { |
19481 | 0 | return impl(std::forward<R>(r), priority_tag<1>{}); |
19482 | 0 | } |
19483 | | }; |
19484 | | |
19485 | | template <> |
19486 | | inline constexpr bool is_raco<reverse_view_fn> = true; |
19487 | | |
19488 | | } // namespace detail |
19489 | | |
19490 | | namespace views { |
19491 | | |
19492 | | NANO_INLINE_VAR(nano::detail::reverse_view_fn, reverse) |
19493 | | |
19494 | | } // namespace views |
19495 | | |
19496 | | NANO_END_NAMESPACE |
19497 | | |
19498 | | #endif |
19499 | | |
19500 | | // nanorange/views/single.hpp |
19501 | | // |
19502 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
19503 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
19504 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
19505 | | |
19506 | | #ifndef NANORANGE_VIEWS_SINGLE_HPP_INCLUDED |
19507 | | #define NANORANGE_VIEWS_SINGLE_HPP_INCLUDED |
19508 | | |
19509 | | NANO_BEGIN_NAMESPACE |
19510 | | |
19511 | | template <typename T> |
19512 | | struct single_view : view_interface<single_view<T>> { |
19513 | | static_assert(copy_constructible<T>); |
19514 | | static_assert(std::is_object<T>::value); |
19515 | | |
19516 | | single_view() = default; |
19517 | | |
19518 | | constexpr explicit single_view(const T& t) : value_(t) {} |
19519 | | |
19520 | | constexpr explicit single_view(T&& t) : value_(std::move(t)) {} |
19521 | | |
19522 | | template <typename... Args, |
19523 | | std::enable_if_t<constructible_from<T, Args...>, int> = 0> |
19524 | | constexpr single_view(std::in_place_t, Args&&... args) |
19525 | | : value_{std::in_place, std::forward<Args>(args)...} |
19526 | | { |
19527 | | } |
19528 | | |
19529 | | constexpr T* begin() noexcept |
19530 | | { |
19531 | | return data(); |
19532 | | } |
19533 | | constexpr const T* begin() const noexcept |
19534 | | { |
19535 | | return data(); |
19536 | | } |
19537 | | |
19538 | | constexpr T* end() noexcept |
19539 | | { |
19540 | | return data() + 1; |
19541 | | } |
19542 | | constexpr const T* end() const noexcept |
19543 | | { |
19544 | | return data() + 1; |
19545 | | } |
19546 | | |
19547 | | static constexpr std::size_t size() |
19548 | | { |
19549 | | return 1; |
19550 | | } |
19551 | | |
19552 | | constexpr T* data() noexcept |
19553 | | { |
19554 | | return value_.operator->(); |
19555 | | } |
19556 | | constexpr const T* data() const noexcept |
19557 | | { |
19558 | | return value_.operator->(); |
19559 | | } |
19560 | | |
19561 | | private: |
19562 | | detail::semiregular_box<T> value_; |
19563 | | }; |
19564 | | |
19565 | | namespace views { |
19566 | | |
19567 | | namespace detail { |
19568 | | |
19569 | | struct single_view_fn { |
19570 | | template <typename T> |
19571 | | constexpr auto operator()(T&& t) const |
19572 | | noexcept(noexcept(single_view{std::forward<T>(t)})) |
19573 | | -> decltype(single_view{std::forward<T>(t)}) |
19574 | | { |
19575 | | return single_view{std::forward<T>(t)}; |
19576 | | } |
19577 | | }; |
19578 | | |
19579 | | } // namespace detail |
19580 | | |
19581 | | NANO_INLINE_VAR(detail::single_view_fn, single) |
19582 | | |
19583 | | } // namespace views |
19584 | | |
19585 | | NANO_END_NAMESPACE |
19586 | | |
19587 | | #endif |
19588 | | // nanorange/views/split.hpp |
19589 | | // |
19590 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
19591 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
19592 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
19593 | | |
19594 | | #ifndef NANORANGE_VIEWS_SPLIT_HPP_INCLUDED |
19595 | | #define NANORANGE_VIEWS_SPLIT_HPP_INCLUDED |
19596 | | |
19597 | | NANO_BEGIN_NAMESPACE |
19598 | | |
19599 | | namespace detail { |
19600 | | |
19601 | | template <auto> |
19602 | | struct require_constant; |
19603 | | |
19604 | | struct tiny_range_concept { |
19605 | | template <typename R> |
19606 | | auto requires_() |
19607 | | -> decltype(std::declval<require_constant< |
19608 | | std::remove_reference_t<R>::size()>>()); |
19609 | | |
19610 | | template <typename R> |
19611 | | static auto test(long) -> std::false_type; |
19612 | | |
19613 | | template <typename R> |
19614 | | static auto test(int) |
19615 | | -> std::enable_if_t<sized_range<R> && |
19616 | | detail::requires_<tiny_range_concept, R> && |
19617 | | (std::remove_reference_t<R>::size() <= 1), |
19618 | | std::true_type>; |
19619 | | }; |
19620 | | |
19621 | | template <typename R> |
19622 | | NANO_CONCEPT tiny_range = decltype(tiny_range_concept::test<R>(0))::value; |
19623 | | |
19624 | | template <typename V, typename P, bool NotForwardRange> |
19625 | | struct split_view_data { |
19626 | | V base_ = V(); |
19627 | | P pattern_ = P(); |
19628 | | }; |
19629 | | |
19630 | | template <typename V, typename P> |
19631 | | struct split_view_data<V, P, true> { |
19632 | | V base_ = V(); |
19633 | | P pattern_ = P(); |
19634 | | iterator_t<V> current_ = iterator_t<V>(); |
19635 | | }; |
19636 | | |
19637 | | } // namespace detail |
19638 | | |
19639 | | namespace split_view_ { |
19640 | | |
19641 | | template <typename V, typename Pattern> |
19642 | | struct split_view : view_interface<split_view<V, Pattern>> { |
19643 | | private: |
19644 | | static_assert(input_range<V>); |
19645 | | static_assert(forward_range<Pattern>); |
19646 | | static_assert(view<V>); |
19647 | | static_assert(view<Pattern>); |
19648 | | static_assert(indirectly_comparable<iterator_t<V>, |
19649 | | iterator_t<Pattern>, |
19650 | | ranges::equal_to>); |
19651 | | static_assert(forward_range<V> || detail::tiny_range<Pattern>); |
19652 | | |
19653 | | detail::split_view_data<V, Pattern, !forward_range<V>> data_{}; |
19654 | | |
19655 | | template <bool> |
19656 | | struct inner_iterator; |
19657 | | |
19658 | | template <bool Const> |
19659 | | struct outer_iterator { |
19660 | | private: |
19661 | | friend struct outer_iterator<!Const>; |
19662 | | friend struct inner_iterator<Const>; |
19663 | | |
19664 | | using Parent = |
19665 | | detail::conditional_t<Const, const split_view, split_view>; |
19666 | | using Base = detail::conditional_t<Const, const V, V>; |
19667 | | Parent* parent_ = nullptr; |
19668 | | iterator_t<Base> current_ = iterator_t<Base>(); |
19669 | | |
19670 | | constexpr decltype(auto) get_current() |
19671 | | { |
19672 | | if constexpr (forward_range<V>) { |
19673 | | return (current_); |
19674 | | } |
19675 | | else { |
19676 | | return (parent_->data_.current_); |
19677 | | } |
19678 | | } |
19679 | | |
19680 | | constexpr decltype(auto) get_current() const |
19681 | | { |
19682 | | if constexpr (forward_range<V>) { |
19683 | | return (current_); |
19684 | | } |
19685 | | else { |
19686 | | return (parent_->data_.current_); |
19687 | | } |
19688 | | } |
19689 | | |
19690 | | constexpr bool done() const |
19691 | | { |
19692 | | return get_current() == ranges::end(parent_->data_.base_); |
19693 | | } |
19694 | | |
19695 | | public: |
19696 | | // FIXME: iterator_concept |
19697 | | using iterator_category = |
19698 | | detail::conditional_t<forward_range<Base>, |
19699 | | forward_iterator_tag, |
19700 | | input_iterator_tag>; |
19701 | | |
19702 | | struct value_type { |
19703 | | private: |
19704 | | outer_iterator i_ = outer_iterator(); |
19705 | | |
19706 | | public: |
19707 | | value_type() = default; |
19708 | | |
19709 | | constexpr explicit value_type(outer_iterator i) |
19710 | | : i_(std::move(i)) |
19711 | | { |
19712 | | } |
19713 | | |
19714 | | constexpr inner_iterator<Const> begin() const |
19715 | | { |
19716 | | return inner_iterator<Const>{i_}; |
19717 | | } |
19718 | | |
19719 | | constexpr default_sentinel_t end() const |
19720 | | { |
19721 | | return default_sentinel; |
19722 | | } |
19723 | | }; |
19724 | | |
19725 | | using difference_type = range_difference_t<Base>; |
19726 | | // Extension: legacy typedefs |
19727 | | using pointer = void; |
19728 | | using reference = value_type; |
19729 | | |
19730 | | outer_iterator() = default; |
19731 | | |
19732 | | template <typename B = Base, |
19733 | | std::enable_if_t<!forward_range<B>, int> = 0> |
19734 | | constexpr explicit outer_iterator(Parent& parent) |
19735 | | : parent_(std::addressof(parent)) |
19736 | | { |
19737 | | } |
19738 | | |
19739 | | template <typename B = Base, |
19740 | | std::enable_if_t<forward_range<B>, int> = 0> |
19741 | | constexpr outer_iterator(Parent& parent, iterator_t<Base> current) |
19742 | | : parent_(std::addressof(parent)), current_(std::move(current)) |
19743 | | { |
19744 | | } |
19745 | | |
19746 | | template < |
19747 | | typename I, |
19748 | | std::enable_if_t<same_as<I, outer_iterator<!Const>>, int> = 0, |
19749 | | bool C = Const, |
19750 | | typename VV = V, |
19751 | | std::enable_if_t< |
19752 | | C && convertible_to<iterator_t<VV>, iterator_t<const VV>>, |
19753 | | int> = 0> |
19754 | | constexpr outer_iterator(I i) |
19755 | | : parent_(i.parent_), current_(std::move(i.current_)) |
19756 | | { |
19757 | | } |
19758 | | |
19759 | | constexpr value_type operator*() const |
19760 | | { |
19761 | | return value_type{*this}; |
19762 | | } |
19763 | | |
19764 | | constexpr outer_iterator& operator++() |
19765 | | { |
19766 | | const auto end = ranges::end(parent_->data_.base_); |
19767 | | if (get_current() == end) { |
19768 | | return *this; |
19769 | | } |
19770 | | const auto [pbegin, pend] = subrange{parent_->data_.pattern_}; |
19771 | | if (pbegin == pend) { |
19772 | | ++get_current(); |
19773 | | } |
19774 | | else { |
19775 | | do { |
19776 | | const auto [b, p] = |
19777 | | ranges::mismatch(get_current(), end, pbegin, pend); |
19778 | | if (p == pend) { |
19779 | | get_current() = b; |
19780 | | break; |
19781 | | } |
19782 | | } while (++get_current() != end); |
19783 | | } |
19784 | | return *this; |
19785 | | } |
19786 | | |
19787 | | constexpr decltype(auto) operator++(int) |
19788 | | { |
19789 | | if constexpr (forward_range<Base>) { |
19790 | | auto tmp = *this; |
19791 | | ++*this; |
19792 | | return tmp; |
19793 | | } |
19794 | | else { |
19795 | | ++*this; |
19796 | | } |
19797 | | } |
19798 | | |
19799 | | template <typename B = Base> |
19800 | | friend constexpr auto operator==(const outer_iterator& x, |
19801 | | const outer_iterator& y) |
19802 | | -> std::enable_if_t<forward_range<B>, bool> |
19803 | | { |
19804 | | return x.current_ == y.current_; |
19805 | | } |
19806 | | |
19807 | | template <typename B = Base> |
19808 | | friend constexpr auto operator!=(const outer_iterator& x, |
19809 | | const outer_iterator& y) |
19810 | | -> std::enable_if_t<forward_range<B>, bool> |
19811 | | { |
19812 | | return !(x == y); |
19813 | | } |
19814 | | |
19815 | | friend constexpr bool operator==(const outer_iterator& x, |
19816 | | default_sentinel_t) |
19817 | | { |
19818 | | return x.done(); |
19819 | | } |
19820 | | |
19821 | | friend constexpr bool operator==(default_sentinel_t d, |
19822 | | const outer_iterator& x) |
19823 | | { |
19824 | | return x == d; |
19825 | | } |
19826 | | |
19827 | | friend constexpr bool operator!=(const outer_iterator& x, |
19828 | | default_sentinel_t d) |
19829 | | { |
19830 | | return !(x == d); |
19831 | | } |
19832 | | |
19833 | | friend constexpr bool operator!=(default_sentinel_t d, |
19834 | | const outer_iterator& x) |
19835 | | { |
19836 | | return !(x == d); |
19837 | | } |
19838 | | }; |
19839 | | |
19840 | | template <bool Const> |
19841 | | struct inner_iterator { |
19842 | | private: |
19843 | | using Base = detail::conditional_t<Const, const V, V>; |
19844 | | static constexpr bool NoReallyGccConst = Const; |
19845 | | outer_iterator<Const> i_ = outer_iterator<NoReallyGccConst>(); |
19846 | | bool incremented_ = false; |
19847 | | |
19848 | | constexpr bool done() const |
19849 | | { |
19850 | | auto cur = i_.get_current(); |
19851 | | auto end = ranges::end(i_.parent_->data_.base_); |
19852 | | if (cur == end) { |
19853 | | return true; |
19854 | | } |
19855 | | auto [pcur, pend] = subrange{i_.parent_->data_.pattern_}; |
19856 | | if (pcur == pend) { |
19857 | | return incremented_; |
19858 | | } |
19859 | | do { |
19860 | | if (*cur != *pcur) { |
19861 | | return false; |
19862 | | } |
19863 | | if (++pcur == pend) { |
19864 | | return true; |
19865 | | } |
19866 | | } while (++cur != end); |
19867 | | return false; |
19868 | | } |
19869 | | |
19870 | | constexpr decltype(auto) get_outer_current() const |
19871 | | { |
19872 | | return i_.get_current(); |
19873 | | } |
19874 | | |
19875 | | public: |
19876 | | using iterator_category = detail::conditional_t< |
19877 | | derived_from<iterator_category_t<iterator_t<Base>>, |
19878 | | forward_iterator_tag>, |
19879 | | forward_iterator_tag, |
19880 | | input_iterator_tag>; |
19881 | | using value_type = range_value_t<Base>; |
19882 | | using difference_type = range_difference_t<Base>; |
19883 | | |
19884 | | inner_iterator() = default; |
19885 | | |
19886 | | constexpr explicit inner_iterator(outer_iterator<Const> i) |
19887 | | : i_(std::move(i)) |
19888 | | { |
19889 | | } |
19890 | | |
19891 | | constexpr decltype(auto) operator*() const |
19892 | | { |
19893 | | return *i_.get_current(); |
19894 | | } |
19895 | | |
19896 | | constexpr inner_iterator& operator++() |
19897 | | { |
19898 | | incremented_ = true; |
19899 | | if constexpr (!forward_range<Base>) { |
19900 | | if constexpr (Pattern::size() == 0) { |
19901 | | return *this; |
19902 | | } |
19903 | | } |
19904 | | ++i_.get_current(); |
19905 | | return *this; |
19906 | | } |
19907 | | |
19908 | | constexpr decltype(auto) operator++(int) |
19909 | | { |
19910 | | if constexpr (forward_range<V>) { |
19911 | | auto tmp = *this; |
19912 | | ++*this; |
19913 | | return tmp; |
19914 | | } |
19915 | | else { |
19916 | | ++*this; |
19917 | | } |
19918 | | } |
19919 | | |
19920 | | template <typename B = Base> |
19921 | | friend constexpr auto operator==(const inner_iterator& x, |
19922 | | const inner_iterator& y) |
19923 | | -> std::enable_if_t<forward_range<B>, bool> |
19924 | | { |
19925 | | return x.get_outer_current() == y.get_outer_current(); |
19926 | | } |
19927 | | |
19928 | | template <typename B = Base> |
19929 | | friend constexpr auto operator!=(const inner_iterator& x, |
19930 | | const inner_iterator& y) |
19931 | | -> std::enable_if_t<forward_range<B>, bool> |
19932 | | { |
19933 | | return !(x == y); |
19934 | | } |
19935 | | |
19936 | | friend constexpr bool operator==(const inner_iterator& x, |
19937 | | default_sentinel_t) |
19938 | | { |
19939 | | return x.done(); |
19940 | | } |
19941 | | |
19942 | | friend constexpr bool operator==(default_sentinel_t d, |
19943 | | const inner_iterator& x) |
19944 | | { |
19945 | | return x == d; |
19946 | | } |
19947 | | |
19948 | | friend constexpr bool operator!=(const inner_iterator& x, |
19949 | | default_sentinel_t d) |
19950 | | { |
19951 | | return !(x == d); |
19952 | | } |
19953 | | |
19954 | | friend constexpr bool operator!=(default_sentinel_t d, |
19955 | | const inner_iterator& x) |
19956 | | { |
19957 | | return !(x == d); |
19958 | | } |
19959 | | |
19960 | | friend constexpr decltype(auto) |
19961 | | iter_move(const inner_iterator& i) noexcept( |
19962 | | noexcept(ranges::iter_move(i.get_outer_current()))) |
19963 | | { |
19964 | | return ranges::iter_move(i.get_outer_current()); |
19965 | | } |
19966 | | |
19967 | | template <typename B = Base> |
19968 | | friend constexpr auto iter_swap( |
19969 | | const inner_iterator& x, |
19970 | | const inner_iterator& |
19971 | | y) noexcept(noexcept(ranges:: |
19972 | | iter_swap(x.get_outer_current(), |
19973 | | y.get_outer_current()))) |
19974 | | -> std::enable_if_t<indirectly_swappable<B>> |
19975 | | { |
19976 | | ranges::iter_swap(x.get_outer_current(), y.get_outer_current()); |
19977 | | } |
19978 | | }; |
19979 | | |
19980 | | public: |
19981 | | split_view() = default; |
19982 | | |
19983 | | constexpr split_view(V base, Pattern pattern) |
19984 | | : data_{std::move(base), std::move(pattern)} |
19985 | | { |
19986 | | } |
19987 | | |
19988 | | template < |
19989 | | typename R, |
19990 | | std::enable_if_t<constructible_from<V, all_view<R>>, int> = 0, |
19991 | | std::enable_if_t< |
19992 | | constructible_from<Pattern, single_view<range_value_t<R>>>, |
19993 | | int> = 0, |
19994 | | std::enable_if_t<input_range<R>, int> = 0> |
19995 | | constexpr split_view(R&& r, range_value_t<R> e) |
19996 | | : data_{views::all(std::forward<R>(r)), single_view{std::move(e)}} |
19997 | | { |
19998 | | } |
19999 | | |
20000 | | constexpr auto begin() |
20001 | | { |
20002 | | if constexpr (forward_range<V>) { |
20003 | | return outer_iterator<detail::simple_view<V>>{ |
20004 | | *this, ranges::begin(data_.base_)}; |
20005 | | } |
20006 | | else { |
20007 | | data_.current_ = ranges::begin(data_.base_); |
20008 | | return outer_iterator<false>{*this}; |
20009 | | } |
20010 | | } |
20011 | | |
20012 | | template <typename VV = V, |
20013 | | std::enable_if_t<forward_range<VV> && forward_range<const VV>, |
20014 | | int> = 0> |
20015 | | constexpr auto begin() const |
20016 | | { |
20017 | | return outer_iterator<true>{*this, ranges::begin(data_.base_)}; |
20018 | | } |
20019 | | |
20020 | | template < |
20021 | | typename VV = V, |
20022 | | std::enable_if_t<forward_range<VV> && common_range<VV>, int> = 0> |
20023 | | constexpr auto end() |
20024 | | { |
20025 | | return outer_iterator<detail::simple_view<V>>{ |
20026 | | *this, ranges::end(data_.base_)}; |
20027 | | } |
20028 | | |
20029 | | constexpr auto end() const |
20030 | | { |
20031 | | if constexpr (forward_range<V> && forward_range<const V> && |
20032 | | common_range<const V>) { |
20033 | | return outer_iterator<true>{*this, ranges::end(data_.base_)}; |
20034 | | } |
20035 | | else { |
20036 | | return default_sentinel; |
20037 | | } |
20038 | | } |
20039 | | }; |
20040 | | |
20041 | | template <typename R, typename P> |
20042 | | split_view(R&&, P&&) -> split_view<all_view<R>, all_view<P>>; |
20043 | | |
20044 | | template <typename R, std::enable_if_t<input_range<R>, int> = 0> |
20045 | | split_view(R&&, range_value_t<R>) |
20046 | | -> split_view<all_view<R>, single_view<range_value_t<R>>>; |
20047 | | |
20048 | | } // namespace split_view_ |
20049 | | |
20050 | | using split_view_::split_view; |
20051 | | |
20052 | | namespace detail { |
20053 | | |
20054 | | struct split_view_fn { |
20055 | | template <typename E, typename F> |
20056 | | constexpr auto operator()(E&& e, F&& f) const |
20057 | | -> decltype(split_view{std::forward<E>(e), std::forward<F>(f)}) |
20058 | | { |
20059 | | return split_view{std::forward<E>(e), std::forward<F>(f)}; |
20060 | | } |
20061 | | |
20062 | | template <typename P> |
20063 | | constexpr auto operator()(P&& p) const |
20064 | | { |
20065 | | return detail::rao_proxy{ |
20066 | | [p = std::forward<P>(p)](auto&& r) mutable |
20067 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
20068 | | -> decltype(split_view{std::forward<decltype(r)>(r), |
20069 | | std::declval<P&&>()}) |
20070 | | #endif |
20071 | | { |
20072 | | return split_view{std::forward<decltype(r)>(r), |
20073 | | std::move(p)}; |
20074 | | }}; |
20075 | | } |
20076 | | }; |
20077 | | |
20078 | | } // namespace detail |
20079 | | |
20080 | | namespace views { |
20081 | | |
20082 | | NANO_INLINE_VAR(nano::detail::split_view_fn, split) |
20083 | | |
20084 | | } |
20085 | | |
20086 | | NANO_END_NAMESPACE |
20087 | | |
20088 | | #endif |
20089 | | |
20090 | | // nanorange/views/take.hpp |
20091 | | // |
20092 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
20093 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
20094 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
20095 | | |
20096 | | #ifndef NANORANGE_VIEWS_TAKE_HPP_INCLUDED |
20097 | | #define NANORANGE_VIEWS_TAKE_HPP_INCLUDED |
20098 | | |
20099 | | NANO_BEGIN_NAMESPACE |
20100 | | |
20101 | | template <typename V> |
20102 | | struct take_view : view_interface<take_view<V>> { |
20103 | | private: |
20104 | | static_assert(view<V>); |
20105 | | |
20106 | | V base_ = V(); |
20107 | | range_difference_t<V> count_ = 0; |
20108 | | |
20109 | | template <bool Const> |
20110 | | struct sentinel { |
20111 | | private: |
20112 | | friend struct sentinel<!Const>; |
20113 | | using Base = detail::conditional_t<Const, const V, V>; |
20114 | | using CI = counted_iterator<iterator_t<Base>>; |
20115 | | |
20116 | | sentinel_t<Base> end_ = sentinel_t<Base>(); |
20117 | | |
20118 | | public: |
20119 | | sentinel() = default; |
20120 | | |
20121 | | constexpr explicit sentinel(sentinel_t<Base> end) : end_(std::move(end)) |
20122 | | { |
20123 | | } |
20124 | | |
20125 | | // Use deduced type to avoid constraint recursion in GCC8 |
20126 | | template <typename S, |
20127 | | std::enable_if_t<same_as<S, sentinel<!Const>>, int> = 0, |
20128 | | bool C = Const, |
20129 | | typename VV = V, |
20130 | | std::enable_if_t< |
20131 | | C && convertible_to<sentinel_t<VV>, sentinel_t<Base>>, |
20132 | | int> = 0> |
20133 | | constexpr explicit sentinel(S s) : end_(std::move(s.end_)) |
20134 | | { |
20135 | | } |
20136 | | |
20137 | | constexpr sentinel_t<Base> base() const |
20138 | | { |
20139 | | return end_; |
20140 | | } |
20141 | | |
20142 | | friend constexpr bool operator==(const CI& y, const sentinel& x) |
20143 | | { |
20144 | | return y.count() == 0 || y.base() == x.end_; |
20145 | | } |
20146 | | |
20147 | | friend constexpr bool operator==(const sentinel& x, const CI& y) |
20148 | | { |
20149 | | return y == x; |
20150 | | } |
20151 | | |
20152 | | friend constexpr bool operator!=(const CI& y, const sentinel& x) |
20153 | | { |
20154 | | return !(y == x); |
20155 | | } |
20156 | | |
20157 | | friend constexpr bool operator!=(const sentinel& x, const CI& y) |
20158 | | { |
20159 | | return !(y == x); |
20160 | | } |
20161 | | }; |
20162 | | |
20163 | | public: |
20164 | | take_view() = default; |
20165 | | |
20166 | | constexpr take_view(V base, range_difference_t<V> count) |
20167 | | : base_(std::move(base)), count_(count) |
20168 | | { |
20169 | | } |
20170 | | |
20171 | | constexpr V base() const |
20172 | | { |
20173 | | return base_; |
20174 | | } |
20175 | | |
20176 | | template <typename VV = V, |
20177 | | std::enable_if_t<!detail::simple_view<VV>, int> = 0> |
20178 | | constexpr auto begin() |
20179 | | { |
20180 | | if constexpr (sized_range<V>) { |
20181 | | if constexpr (random_access_range<V>) { |
20182 | | return ranges::begin(base_); |
20183 | | } |
20184 | | else { |
20185 | | // N.B spec doesn't static_cast here, but I'm pretty |
20186 | | // sure it should |
20187 | | return counted_iterator{ |
20188 | | ranges::begin(base_), |
20189 | | static_cast<range_difference_t<V>>(size())}; |
20190 | | } |
20191 | | } |
20192 | | else { |
20193 | | return counted_iterator{ranges::begin(base_), count_}; |
20194 | | } |
20195 | | } |
20196 | | |
20197 | | template <typename VV = V, std::enable_if_t<range<const VV>, int> = 0> |
20198 | | constexpr auto begin() const |
20199 | | { |
20200 | | if constexpr (sized_range<const V>) { |
20201 | | if constexpr (random_access_range<V>) { |
20202 | | return ranges::begin(base_); |
20203 | | } |
20204 | | else { |
20205 | | // N.B spec doesn't static_cast here, but I'm pretty |
20206 | | // sure it should |
20207 | | return counted_iterator{ |
20208 | | ranges::begin(base_), |
20209 | | static_cast<range_difference_t<V>>(size())}; |
20210 | | } |
20211 | | } |
20212 | | else { |
20213 | | return counted_iterator{ranges::begin(base_), count_}; |
20214 | | } |
20215 | | } |
20216 | | |
20217 | | template <typename VV = V, |
20218 | | std::enable_if_t<!detail::simple_view<VV>, int> = 0> |
20219 | | constexpr auto end() |
20220 | | { |
20221 | | if constexpr (sized_range<V>) { |
20222 | | if constexpr (random_access_range<V>) { |
20223 | | return ranges::begin(base_) + size(); |
20224 | | } |
20225 | | else { |
20226 | | return default_sentinel; |
20227 | | } |
20228 | | } |
20229 | | else { |
20230 | | return sentinel<false>{ranges::end(base_)}; |
20231 | | } |
20232 | | } |
20233 | | |
20234 | | template <typename VV = V, std::enable_if_t<range<const VV>, int> = 0> |
20235 | | constexpr auto end() const |
20236 | | { |
20237 | | if constexpr (sized_range<const V>) { |
20238 | | if constexpr (random_access_range<const V>) { |
20239 | | return ranges::begin(base_) + size(); |
20240 | | } |
20241 | | else { |
20242 | | return default_sentinel; |
20243 | | } |
20244 | | } |
20245 | | else { |
20246 | | return sentinel<true>{ranges::end(base_)}; |
20247 | | } |
20248 | | } |
20249 | | |
20250 | | template <typename VV = V, std::enable_if_t<sized_range<VV>, int> = 0> |
20251 | | constexpr auto size() |
20252 | | { |
20253 | | auto n = ranges::size(base_); |
20254 | | return ranges::min(n, static_cast<decltype(n)>(count_)); |
20255 | | } |
20256 | | |
20257 | | template <typename VV = V, std::enable_if_t<sized_range<const VV>, int> = 0> |
20258 | | constexpr auto size() const |
20259 | | { |
20260 | | auto n = ranges::size(base_); |
20261 | | return ranges::min(n, static_cast<decltype(n)>(count_)); |
20262 | | } |
20263 | | }; |
20264 | | |
20265 | | template <typename R, std::enable_if_t<range<R>, int> = 0> |
20266 | | take_view(R&&, range_difference_t<R>) -> take_view<all_view<R>>; |
20267 | | |
20268 | | namespace detail { |
20269 | | |
20270 | | #ifdef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
20271 | | template <typename R> |
20272 | | using take_view_helper_t = take_view<all_view<R>>; |
20273 | | #endif |
20274 | | |
20275 | | struct take_view_fn { |
20276 | | template <typename C> |
20277 | | constexpr auto operator()(C c) const |
20278 | | { |
20279 | | return detail::rao_proxy{[c = std::move(c)](auto&& r) mutable |
20280 | | #ifdef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
20281 | | -> take_view_helper_t<decltype(r)> |
20282 | | #else |
20283 | | -> decltype(take_view{ |
20284 | | std::forward<decltype(r)>(r), |
20285 | | std::declval<C&&>()}) |
20286 | | #endif |
20287 | | { |
20288 | | return take_view{ |
20289 | | std::forward<decltype(r)>(r), |
20290 | | std::move(c)}; |
20291 | | }}; |
20292 | | } |
20293 | | |
20294 | | template <typename E, typename F> |
20295 | | constexpr auto operator()(E&& e, F&& f) const |
20296 | | -> decltype(take_view{std::forward<E>(e), std::forward<F>(f)}) |
20297 | | { |
20298 | | return take_view{std::forward<E>(e), std::forward<F>(f)}; |
20299 | | } |
20300 | | }; |
20301 | | |
20302 | | } // namespace detail |
20303 | | |
20304 | | namespace views { |
20305 | | |
20306 | | NANO_INLINE_VAR(nano::detail::take_view_fn, take) |
20307 | | |
20308 | | } |
20309 | | |
20310 | | NANO_END_NAMESPACE |
20311 | | |
20312 | | #endif |
20313 | | |
20314 | | // nanorange/views/take_while.hpp |
20315 | | // |
20316 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
20317 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
20318 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
20319 | | |
20320 | | #ifndef NANORANGE_VIEWS_TAKE_WHILE_HPP_INCLUDED |
20321 | | #define NANORANGE_VIEWS_TAKE_WHILE_HPP_INCLUDED |
20322 | | |
20323 | | NANO_BEGIN_NAMESPACE |
20324 | | |
20325 | | template <typename R, typename Pred> |
20326 | | struct take_while_view : view_interface<take_while_view<R, Pred>> { |
20327 | | private: |
20328 | | static_assert(view<R>); |
20329 | | // FIXME: Should be input_range (GCC9) |
20330 | | static_assert(input_iterator<iterator_t<R>>); |
20331 | | static_assert(std::is_object_v<Pred>); |
20332 | | static_assert(indirect_unary_predicate<const Pred, iterator_t<R>>); |
20333 | | |
20334 | | template <bool Const> |
20335 | | struct sentinel { |
20336 | | private: |
20337 | | friend struct sentinel<!Const>; |
20338 | | using base_t = detail::conditional_t<Const, const R, R>; |
20339 | | sentinel_t<base_t> end_ = sentinel_t<base_t>(); |
20340 | | const Pred* pred_{}; |
20341 | | |
20342 | | public: |
20343 | | sentinel() = default; |
20344 | | |
20345 | | constexpr explicit sentinel(sentinel_t<base_t>(end), const Pred* pred) |
20346 | | : end_(std::move(end)), pred_(pred) |
20347 | | { |
20348 | | } |
20349 | | |
20350 | | // Use deduced type to avoid constraint recursion in GCC8 |
20351 | | template <typename S, |
20352 | | std::enable_if_t<same_as<S, sentinel<!Const>>, int> = 0, |
20353 | | bool C = Const, |
20354 | | typename VV = R, |
20355 | | std::enable_if_t< |
20356 | | C && convertible_to<sentinel_t<VV>, sentinel_t<base_t>>, |
20357 | | int> = 0> |
20358 | | constexpr sentinel(S s) : end_(std::move(s.end_)), pred_(s.pred_) |
20359 | | { |
20360 | | } |
20361 | | |
20362 | | constexpr sentinel_t<base_t> base() const |
20363 | | { |
20364 | | return end_; |
20365 | | } |
20366 | | |
20367 | | // Make these friend functions templates to keep MSVC happy |
20368 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
20369 | | template <typename = void> |
20370 | | #endif |
20371 | | friend constexpr bool operator==(const iterator_t<base_t>& x, |
20372 | | const sentinel& y) |
20373 | | { |
20374 | | return y.end_ == x || !nano::invoke(*y.pred_, *x); |
20375 | | } |
20376 | | |
20377 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
20378 | | template <typename = void> |
20379 | | #endif |
20380 | | friend constexpr bool operator==(const sentinel& y, |
20381 | | const iterator_t<base_t>& x) |
20382 | | { |
20383 | | return x == y; |
20384 | | } |
20385 | | |
20386 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
20387 | | template <typename = void> |
20388 | | #endif |
20389 | | friend constexpr bool operator!=(const iterator_t<base_t>& x, |
20390 | | const sentinel& y) |
20391 | | { |
20392 | | return !(x == y); |
20393 | | } |
20394 | | |
20395 | | #if (defined(_MSC_VER) && _MSC_VER < 1922) |
20396 | | template <typename = void> |
20397 | | #endif |
20398 | | friend constexpr bool operator!=(const sentinel& y, |
20399 | | const iterator_t<base_t>& x) |
20400 | | { |
20401 | | return !(x == y); |
20402 | | } |
20403 | | }; |
20404 | | |
20405 | | R base_; |
20406 | | detail::semiregular_box<Pred> pred_; |
20407 | | |
20408 | | public: |
20409 | | take_while_view() = default; |
20410 | | |
20411 | | constexpr take_while_view(R base, Pred pred) |
20412 | | : base_(std::move(base)), pred_(std::move(pred)) |
20413 | | { |
20414 | | } |
20415 | | |
20416 | | constexpr R base() const |
20417 | | { |
20418 | | return base_; |
20419 | | } |
20420 | | |
20421 | | constexpr const Pred& pred() const |
20422 | | { |
20423 | | return *pred_; |
20424 | | } |
20425 | | |
20426 | | template <typename RR = R, |
20427 | | std::enable_if_t<!detail::simple_view<RR>, int> = 0> |
20428 | | constexpr auto begin() |
20429 | | { |
20430 | | return ranges::begin(base_); |
20431 | | } |
20432 | | |
20433 | | template <typename RR = R, std::enable_if_t<range<const RR>, int> = 0> |
20434 | | constexpr auto begin() const |
20435 | | { |
20436 | | return ranges::begin(base_); |
20437 | | } |
20438 | | |
20439 | | template <typename RR = R, |
20440 | | std::enable_if_t<!detail::simple_view<RR>, int> = 0> |
20441 | | constexpr auto end() |
20442 | | { |
20443 | | return sentinel<false>{ranges::end(base_), std::addressof(*pred_)}; |
20444 | | } |
20445 | | |
20446 | | template <typename RR = R, std::enable_if_t<range<const RR>, int> = 0> |
20447 | | constexpr auto end() const |
20448 | | { |
20449 | | return sentinel<true>{ranges::end(base_), std::addressof(*pred_)}; |
20450 | | } |
20451 | | }; |
20452 | | |
20453 | | template <typename R, typename Pred> |
20454 | | take_while_view(R&&, Pred) -> take_while_view<all_view<R>, Pred>; |
20455 | | |
20456 | | namespace detail { |
20457 | | |
20458 | | struct take_while_view_fn { |
20459 | | template <typename E, typename F> |
20460 | | constexpr auto operator()(E&& e, F&& f) const |
20461 | | -> decltype(take_while_view{std::forward<E>(e), std::forward<F>(f)}) |
20462 | | { |
20463 | | return take_while_view{std::forward<E>(e), std::forward<F>(f)}; |
20464 | | } |
20465 | | |
20466 | | template <typename Pred> |
20467 | | constexpr auto operator()(Pred&& pred) const |
20468 | | { |
20469 | | return detail::rao_proxy{ |
20470 | | [p = std::forward<Pred>(pred)](auto&& r) mutable |
20471 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
20472 | | -> decltype(take_while_view{std::forward<decltype(r)>(r), |
20473 | | std::declval<Pred&&>()}) |
20474 | | #endif |
20475 | | { |
20476 | | return take_while_view{std::forward<decltype(r)>(r), |
20477 | | std::move(p)}; |
20478 | | }}; |
20479 | | } |
20480 | | }; |
20481 | | |
20482 | | } // namespace detail |
20483 | | |
20484 | | namespace views { |
20485 | | |
20486 | | NANO_INLINE_VAR(nano::detail::take_while_view_fn, take_while) |
20487 | | |
20488 | | } |
20489 | | |
20490 | | NANO_END_NAMESPACE |
20491 | | |
20492 | | #endif |
20493 | | |
20494 | | // nanorange/views/transform.hpp |
20495 | | // |
20496 | | // Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) |
20497 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
20498 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
20499 | | |
20500 | | #ifndef NANORANGE_VIEWS_TRANSFORM_HPP_INCLUDED |
20501 | | #define NANORANGE_VIEWS_TRANSFORM_HPP_INCLUDED |
20502 | | |
20503 | | NANO_BEGIN_NAMESPACE |
20504 | | |
20505 | | namespace transform_view_ { |
20506 | | |
20507 | | template <typename V, typename F> |
20508 | | struct transform_view : view_interface<transform_view<V, F>> { |
20509 | | private: |
20510 | | // FIXME: Weird GCC9 bug strikes again! |
20511 | | // These two conditions are equivalent to input_range<V>, but if we test |
20512 | | // that directly with GCC9 then it fails?! |
20513 | | static_assert(range<V>); |
20514 | | static_assert(input_iterator<iterator_t<V>>); |
20515 | | static_assert(view<V>); |
20516 | | static_assert(copy_constructible<F>); |
20517 | | static_assert(std::is_object_v<F>); |
20518 | | static_assert(regular_invocable<F&, range_reference_t<V>>); |
20519 | | |
20520 | | template <bool> |
20521 | | struct sentinel; |
20522 | | |
20523 | | template <bool Const> |
20524 | | struct iterator { |
20525 | | private: |
20526 | | friend struct iterator<!Const>; |
20527 | | friend struct sentinel<Const>; |
20528 | | |
20529 | | using Parent = detail:: |
20530 | | conditional_t<Const, const transform_view, transform_view>; |
20531 | | using Base = detail::conditional_t<Const, const V, V>; |
20532 | | |
20533 | | iterator_t<Base> current_ = iterator_t<Base>(); |
20534 | | Parent* parent_ = nullptr; |
20535 | | |
20536 | | static constexpr bool iter_move_noexcept_helper = |
20537 | | noexcept(nano::invoke(*parent_->fun_, *current_)); |
20538 | | |
20539 | | public: |
20540 | | using iterator_category = detail::conditional_t< |
20541 | | derived_from<iterator_category_t<iterator_t<Base>>, |
20542 | | contiguous_iterator_tag>, |
20543 | | random_access_iterator_tag, |
20544 | | iterator_category_t<iterator_t<Base>>>; |
20545 | | |
20546 | | using value_type = |
20547 | | remove_cvref_t<invoke_result_t<F&, range_reference_t<Base>>>; |
20548 | | using difference_type = range_difference_t<Base>; |
20549 | | // Extension: legacy typedefs |
20550 | | using pointer = void; |
20551 | | using reference = invoke_result_t<F&, range_reference_t<Base>>; |
20552 | | |
20553 | | iterator() = default; |
20554 | | |
20555 | | constexpr iterator(Parent& parent, iterator_t<Base> current) |
20556 | | : current_(std::move(current)), parent_(std::addressof(parent)) |
20557 | | { |
20558 | | } |
20559 | | |
20560 | | template <typename I, |
20561 | | std::enable_if_t<same_as<I, iterator<!Const>>, int> = 0, |
20562 | | bool C = Const, |
20563 | | typename VV = V, |
20564 | | std::enable_if_t< |
20565 | | C && convertible_to<iterator_t<VV>, iterator_t<Base>>, |
20566 | | int> = 0> |
20567 | | constexpr iterator(I i) |
20568 | | : current_(std::move(i.current_)), parent_(i.parent_) |
20569 | | { |
20570 | | } |
20571 | | |
20572 | | constexpr iterator_t<Base> base() const |
20573 | | { |
20574 | | return current_; |
20575 | | } |
20576 | | |
20577 | | constexpr decltype(auto) operator*() const |
20578 | | { |
20579 | | return nano::invoke(*parent_->fun_, *current_); |
20580 | | } |
20581 | | |
20582 | | constexpr iterator& operator++() |
20583 | | { |
20584 | | ++current_; |
20585 | | return *this; |
20586 | | } |
20587 | | |
20588 | | constexpr auto operator++(int) |
20589 | | { |
20590 | | if constexpr (forward_range<Base>) { |
20591 | | auto tmp = *this; |
20592 | | ++*this; |
20593 | | return tmp; |
20594 | | } |
20595 | | else { |
20596 | | ++current_; |
20597 | | } |
20598 | | } |
20599 | | |
20600 | | template <typename B = Base> |
20601 | | constexpr auto operator--() |
20602 | | -> std::enable_if_t<bidirectional_range<B>, iterator&> |
20603 | | { |
20604 | | --current_; |
20605 | | return *this; |
20606 | | } |
20607 | | |
20608 | | template <typename B = Base> |
20609 | | constexpr auto operator--(int) |
20610 | | -> std::enable_if_t<bidirectional_range<B>, iterator> |
20611 | | { |
20612 | | auto tmp = *this; |
20613 | | --*this; |
20614 | | return tmp; |
20615 | | } |
20616 | | |
20617 | | template <typename B = Base> |
20618 | | constexpr auto operator+=(difference_type n) |
20619 | | -> std::enable_if_t<random_access_range<B>, iterator&> |
20620 | | { |
20621 | | current_ += n; |
20622 | | return *this; |
20623 | | } |
20624 | | |
20625 | | template <typename B = Base> |
20626 | | constexpr auto operator-=(difference_type n) |
20627 | | -> std::enable_if_t<random_access_range<B>, iterator&> |
20628 | | { |
20629 | | current_ -= n; |
20630 | | return *this; |
20631 | | } |
20632 | | |
20633 | | template <typename B = Base, |
20634 | | typename = std::enable_if_t<random_access_range<B>>> |
20635 | | constexpr decltype(auto) operator[](difference_type n) const |
20636 | | { |
20637 | | return nano::invoke(*parent_->fun_, current_[n]); |
20638 | | } |
20639 | | |
20640 | | template <typename B = Base> |
20641 | | friend constexpr auto operator==(const iterator& x, |
20642 | | const iterator& y) |
20643 | | -> std::enable_if_t<equality_comparable<iterator_t<B>>, bool> |
20644 | | { |
20645 | | return x.current_ == y.current_; |
20646 | | } |
20647 | | |
20648 | | template <typename B = Base> |
20649 | | friend constexpr auto operator!=(const iterator& x, |
20650 | | const iterator& y) |
20651 | | -> std::enable_if_t<equality_comparable<iterator_t<B>>, bool> |
20652 | | { |
20653 | | return !(x == y); |
20654 | | } |
20655 | | |
20656 | | template <typename B = Base> |
20657 | | friend constexpr auto operator<(const iterator& x, |
20658 | | const iterator& y) |
20659 | | -> std::enable_if_t<random_access_range<B>, bool> |
20660 | | { |
20661 | | return x.current_ < y.current_; |
20662 | | } |
20663 | | |
20664 | | template <typename B = Base> |
20665 | | friend constexpr auto operator>(const iterator& x, |
20666 | | const iterator& y) |
20667 | | -> std::enable_if_t<random_access_range<B>, bool> |
20668 | | { |
20669 | | return y < x; |
20670 | | } |
20671 | | |
20672 | | template <typename B = Base> |
20673 | | friend constexpr auto operator<=(const iterator& x, |
20674 | | const iterator& y) |
20675 | | -> std::enable_if_t<random_access_range<B>, bool> |
20676 | | { |
20677 | | return !(y < x); |
20678 | | } |
20679 | | |
20680 | | template <typename B = Base> |
20681 | | friend constexpr auto operator>=(const iterator& x, |
20682 | | const iterator& y) |
20683 | | -> std::enable_if_t<random_access_range<B>, bool> |
20684 | | { |
20685 | | return !(x < y); |
20686 | | } |
20687 | | |
20688 | | template <typename B = Base> |
20689 | | friend constexpr auto operator+(iterator i, difference_type n) |
20690 | | -> std::enable_if_t<random_access_range<B>, iterator> |
20691 | | { |
20692 | | return iterator{*i.parent_, i.current_ + n}; |
20693 | | } |
20694 | | |
20695 | | template <typename B = Base> |
20696 | | friend constexpr auto operator+(difference_type n, iterator i) |
20697 | | -> std::enable_if_t<random_access_range<B>, iterator> |
20698 | | { |
20699 | | return iterator{*i.parent_, i.current_ + n}; |
20700 | | } |
20701 | | |
20702 | | template <typename B = Base> |
20703 | | friend constexpr auto operator-(iterator i, difference_type n) |
20704 | | -> std::enable_if_t<random_access_range<B>, iterator> |
20705 | | { |
20706 | | return iterator{*i.parent_, i.current_ - n}; |
20707 | | } |
20708 | | |
20709 | | template <typename B = Base> |
20710 | | friend constexpr auto operator-(const iterator& x, |
20711 | | const iterator& y) |
20712 | | -> std::enable_if_t<random_access_range<B>, difference_type> |
20713 | | { |
20714 | | return x.current_ - y.current_; |
20715 | | } |
20716 | | |
20717 | | friend constexpr decltype(auto) iter_move( |
20718 | | const iterator& i) noexcept(iter_move_noexcept_helper) |
20719 | | { |
20720 | | if constexpr (std::is_lvalue_reference_v<decltype(*i)>) { |
20721 | | return std::move(*i); |
20722 | | } |
20723 | | else { |
20724 | | return *i; |
20725 | | } |
20726 | | } |
20727 | | |
20728 | | template <typename B = Base> |
20729 | | friend constexpr auto |
20730 | | iter_swap(const iterator& x, const iterator& y) noexcept( |
20731 | | noexcept(ranges::iter_swap(x.current_, y.current_))) |
20732 | | -> std::enable_if_t<indirectly_swappable<iterator_t<B>>> |
20733 | | { |
20734 | | return ranges::iter_swap(x.current_, y.current_); |
20735 | | } |
20736 | | }; |
20737 | | |
20738 | | template <bool Const> |
20739 | | struct sentinel { |
20740 | | private: |
20741 | | friend struct sentinel<!Const>; |
20742 | | |
20743 | | using Parent = detail:: |
20744 | | conditional_t<Const, const transform_view, transform_view>; |
20745 | | using Base = detail::conditional_t<Const, const V, V>; |
20746 | | sentinel_t<Base> end_ = sentinel_t<Base>(); |
20747 | | |
20748 | | public: |
20749 | | sentinel() = default; |
20750 | | |
20751 | | constexpr explicit sentinel(sentinel_t<Base> end) |
20752 | | : end_(std::move(end)) |
20753 | | { |
20754 | | } |
20755 | | |
20756 | | template <typename S, |
20757 | | std::enable_if_t<same_as<S, sentinel<!Const>>, int> = 0, |
20758 | | bool C = Const, |
20759 | | typename VV = V, |
20760 | | std::enable_if_t< |
20761 | | C && convertible_to<sentinel_t<VV>, sentinel_t<Base>>, |
20762 | | int> = 0> |
20763 | | constexpr sentinel(S i) : end_(std::move(i.end_)) |
20764 | | { |
20765 | | } |
20766 | | |
20767 | | constexpr sentinel_t<Base> base() |
20768 | | { |
20769 | | return end_; |
20770 | | } |
20771 | | |
20772 | | friend constexpr bool operator==(const iterator<Const>& x, |
20773 | | const sentinel& y) |
20774 | | { |
20775 | | return x.base() == y.end_; |
20776 | | } |
20777 | | |
20778 | | friend constexpr bool operator==(const sentinel& x, |
20779 | | const iterator<Const>& y) |
20780 | | { |
20781 | | return x.end_ == y.base(); |
20782 | | } |
20783 | | |
20784 | | friend constexpr bool operator!=(const iterator<Const>& x, |
20785 | | const sentinel& y) |
20786 | | { |
20787 | | return !(x == y); |
20788 | | } |
20789 | | |
20790 | | friend constexpr bool operator!=(const sentinel& x, |
20791 | | const iterator<Const>& y) |
20792 | | { |
20793 | | return !(x == y); |
20794 | | } |
20795 | | |
20796 | | template <typename B = Base> |
20797 | | friend constexpr auto operator-(const iterator<Const>& x, |
20798 | | const sentinel& y) |
20799 | | -> std::enable_if_t< |
20800 | | sized_sentinel_for<sentinel_t<B>, iterator_t<B>>, |
20801 | | range_difference_t<B>> |
20802 | | { |
20803 | | return x.current_ - y.end_; |
20804 | | } |
20805 | | |
20806 | | template <typename B = Base> |
20807 | | friend constexpr auto operator-(const sentinel& x, |
20808 | | const iterator<Const>& y) |
20809 | | -> std::enable_if_t< |
20810 | | sized_sentinel_for<sentinel_t<B>, iterator_t<B>>, |
20811 | | range_difference_t<B>> |
20812 | | { |
20813 | | x.end_ - y.current_; |
20814 | | } |
20815 | | }; |
20816 | | |
20817 | | V base_ = V(); |
20818 | | detail::semiregular_box<F> fun_; |
20819 | | |
20820 | | public: |
20821 | | transform_view() = default; |
20822 | | |
20823 | | constexpr transform_view(V base, F fun) |
20824 | | : base_(std::move(base)), fun_(std::move(fun)) |
20825 | | { |
20826 | | } |
20827 | | |
20828 | | constexpr V base() const |
20829 | | { |
20830 | | return base_; |
20831 | | } |
20832 | | |
20833 | | constexpr iterator<false> begin() |
20834 | | { |
20835 | | return iterator<false>{*this, ranges::begin(base_)}; |
20836 | | } |
20837 | | |
20838 | | template < |
20839 | | typename VV = V, |
20840 | | std::enable_if_t< |
20841 | | range<const VV> && |
20842 | | regular_invocable<const F&, range_reference_t<const VV>>, |
20843 | | int> = 0> |
20844 | | constexpr iterator<true> begin() const |
20845 | | { |
20846 | | return iterator<true>{*this, ranges::begin(base_)}; |
20847 | | } |
20848 | | |
20849 | | constexpr auto end() |
20850 | | { |
20851 | | if constexpr (common_range<V>) { |
20852 | | return iterator<false>{*this, ranges::end(base_)}; |
20853 | | } |
20854 | | else { |
20855 | | return sentinel<false>{ranges::end(base_)}; |
20856 | | } |
20857 | | } |
20858 | | |
20859 | | template < |
20860 | | typename VV = V, |
20861 | | std::enable_if_t< |
20862 | | range<const VV> && |
20863 | | regular_invocable<const F&, range_reference_t<const VV>>, |
20864 | | int> = 0> |
20865 | | constexpr auto end() const |
20866 | | { |
20867 | | if constexpr (common_range<V>) { |
20868 | | return iterator<true>{*this, ranges::end(base_)}; |
20869 | | } |
20870 | | else { |
20871 | | return sentinel<true>{ranges::end(base_)}; |
20872 | | } |
20873 | | } |
20874 | | |
20875 | | template <typename VV = V, std::enable_if_t<sized_range<VV>, int> = 0> |
20876 | | constexpr auto size() |
20877 | | { |
20878 | | return ranges::size(base_); |
20879 | | } |
20880 | | |
20881 | | template <typename VV = V, |
20882 | | std::enable_if_t<sized_range<const VV>, int> = 0> |
20883 | | constexpr auto size() const |
20884 | | { |
20885 | | return ranges::size(base_); |
20886 | | } |
20887 | | }; |
20888 | | |
20889 | | template <typename R, |
20890 | | typename F, |
20891 | | std::enable_if_t< |
20892 | | input_range<all_view<R>> && copy_constructible<F> && |
20893 | | std::is_object_v<F> && |
20894 | | regular_invocable<F&, range_reference_t<all_view<R>>>, |
20895 | | int> = 0> |
20896 | | transform_view(R&&, F) -> transform_view<all_view<R>, F>; |
20897 | | |
20898 | | } // namespace transform_view_ |
20899 | | |
20900 | | using transform_view_::transform_view; |
20901 | | |
20902 | | namespace detail { |
20903 | | |
20904 | | struct transform_view_fn { |
20905 | | template <typename E, typename F> |
20906 | | constexpr auto operator()(E&& e, F&& f) const |
20907 | | -> decltype(transform_view{std::forward<E>(e), std::forward<F>(f)}) |
20908 | | { |
20909 | | return transform_view{std::forward<E>(e), std::forward<F>(f)}; |
20910 | | } |
20911 | | |
20912 | | template <typename F> |
20913 | | constexpr auto operator()(F f) const |
20914 | | { |
20915 | | return detail::rao_proxy{ |
20916 | | [f = std::move(f)](auto&& r) mutable |
20917 | | #ifndef NANO_MSVC_LAMBDA_PIPE_WORKAROUND |
20918 | | -> decltype(transform_view{std::forward<decltype(r)>(r), |
20919 | | std::declval<F&&>()}) |
20920 | | #endif |
20921 | | { |
20922 | | return transform_view{std::forward<decltype(r)>(r), |
20923 | | std::move(f)}; |
20924 | | }}; |
20925 | | } |
20926 | | }; |
20927 | | |
20928 | | } // namespace detail |
20929 | | |
20930 | | namespace views { |
20931 | | |
20932 | | NANO_INLINE_VAR(nano::detail::transform_view_fn, transform) |
20933 | | |
20934 | | } |
20935 | | |
20936 | | NANO_END_NAMESPACE |
20937 | | |
20938 | | #endif |
20939 | | |
20940 | | #endif |
20941 | | |
20942 | | #endif // NANORANGE_HPP_INCLUDED |